From a673198c814450f01e618f7f347e80f1bbb1e118 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Fri, 20 Oct 2023 12:20:16 -0400 Subject: [PATCH 01/12] Roll Flutter from c2bd2c1175f5 to 0883cb2e962d (24 revisions) (#5192) https://github.com/flutter/flutter/compare/c2bd2c1175f5...0883cb2e962d 2023-10-20 engine-flutter-autoroll@skia.org Roll Packages from 09c6b1152070 to be915be92708 (6 revisions) (flutter/flutter#136964) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from de780872533c to 9b88ff83fd82 (4 revisions) (flutter/flutter#136959) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 1e107c21328a to de780872533c (1 revision) (flutter/flutter#136952) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from fd33e7e75eac to 1e107c21328a (1 revision) (flutter/flutter#136949) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 9dd59f7fcff9 to fd33e7e75eac (1 revision) (flutter/flutter#136942) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from cc3356c0e68f to 9dd59f7fcff9 (1 revision) (flutter/flutter#136935) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 504a99d93f42 to cc3356c0e68f (2 revisions) (flutter/flutter#136934) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from 503b84295462 to 504a99d93f42 (3 revisions) (flutter/flutter#136930) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from 3b0469b0c718 to 503b84295462 (1 revision) (flutter/flutter#136928) 2023-10-19 katelovett@google.com Revert "[Velocity Tracker] Fix: Issue 97761: Flutter Scrolling does not match iOS; inadvertent scrolling when user lifts up finger" (flutter/flutter#136905) 2023-10-19 christopherfujino@gmail.com [flutter_tools] move build_preview_test from commands/permeable to integration shard (flutter/flutter#136912) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from b40042ebb95b to 3b0469b0c718 (2 revisions) (flutter/flutter#136922) 2023-10-19 andrewrkolos@gmail.com do not include entries from `--dart-define-from-file` files in the gradle config or environment during build (flutter/flutter#136865) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from bfd2ffb9a8bc to b40042ebb95b (2 revisions) (flutter/flutter#136915) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from 9d49175618f5 to bfd2ffb9a8bc (2 revisions) (flutter/flutter#136910) 2023-10-19 36861262+QuncCccccc@users.noreply.github.com Allow users to customize search algorithm in `DropdownMenu` (flutter/flutter#136848) 2023-10-19 21270878+elliette@users.noreply.github.com Upgrade Flutter deps to pull in latest vm_service and dwds (flutter/flutter#136734) 2023-10-19 15619084+vashworth@users.noreply.github.com [Reland] Skip injecting Bonjour settings when port publication is disabled (flutter/flutter#136842) 2023-10-19 sokolovskyi.konstantin@gmail.com _DefaultTabControllerState should dispose all created TabContoller instances. (flutter/flutter#136608) 2023-10-19 gspencergoog@users.noreply.github.com Reland: "Add code for updating `focusedChild` when removing grandchildren from scope" (flutter/flutter#136899) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from 418dce4feaf7 to 9d49175618f5 (1 revision) (flutter/flutter#136901) 2023-10-19 34871572+gmackall@users.noreply.github.com Unmark linux_android platform_channels_benchmarks as flaky (flutter/flutter#136838) 2023-10-19 engine-flutter-autoroll@skia.org Roll Packages from 14aa69e2e54c to 09c6b1152070 (4 revisions) (flutter/flutter#136896) 2023-10-19 engine-flutter-autoroll@skia.org Roll Flutter Engine from 28cb2508b8e0 to 418dce4feaf7 (2 revisions) (flutter/flutter#136895) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC rmistry@google.com,stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- .ci/flutter_master.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index 71fd5e09ee5..9ce6aa0007d 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -c2bd2c1175f5b81e9543955760aec5b876b4e57e +0883cb2e962d485c722c1e5628366ba759815454 From 2807d05e8b6c20ac315e8715bb5bb29debc60400 Mon Sep 17 00:00:00 2001 From: Kenzie Davisson <43759233+kenzieschmoll@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:53:06 -0700 Subject: [PATCH 02/12] Add '--no-tree-shake-icons' option to `BenchmarkServer` (#5186) --- packages/web_benchmarks/CHANGELOG.md | 5 +++ packages/web_benchmarks/lib/server.dart | 2 + packages/web_benchmarks/lib/src/runner.dart | 7 +++ packages/web_benchmarks/pubspec.yaml | 2 +- .../lib/{aboutpage.dart => about_page.dart} | 0 .../test_app/lib/benchmarks/runner.dart | 4 +- .../lib/{homepage.dart => home_page.dart} | 0 .../testing/test_app/lib/icon_page.dart | 45 +++++++++++++++++++ .../testing/test_app/lib/main.dart | 6 ++- .../testing/test_app/pubspec.yaml | 3 +- .../testing/web_benchmarks_test.dart | 1 + 11 files changed, 68 insertions(+), 7 deletions(-) rename packages/web_benchmarks/testing/test_app/lib/{aboutpage.dart => about_page.dart} (100%) rename packages/web_benchmarks/testing/test_app/lib/{homepage.dart => home_page.dart} (100%) create mode 100644 packages/web_benchmarks/testing/test_app/lib/icon_page.dart diff --git a/packages/web_benchmarks/CHANGELOG.md b/packages/web_benchmarks/CHANGELOG.md index d167518850c..7222ae8557f 100644 --- a/packages/web_benchmarks/CHANGELOG.md +++ b/packages/web_benchmarks/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.0+8 + +* Adds an optional parameter `treeShakeIcons` to `serveWebBenchmark`. +* Adds a required and named parameter `treeShakeIcons` to `BenchmarkServer`. + ## 0.1.0+7 * Updates `package:process` version constraints. diff --git a/packages/web_benchmarks/lib/server.dart b/packages/web_benchmarks/lib/server.dart index 7327e1aa08b..7d16b79940e 100644 --- a/packages/web_benchmarks/lib/server.dart +++ b/packages/web_benchmarks/lib/server.dart @@ -46,6 +46,7 @@ Future serveWebBenchmark({ int benchmarkServerPort = defaultBenchmarkServerPort, int chromeDebugPort = defaultChromeDebugPort, bool headless = true, + bool treeShakeIcons = true, }) async { // Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy. Logger.root.level = Level.INFO; @@ -57,5 +58,6 @@ Future serveWebBenchmark({ benchmarkServerPort: benchmarkServerPort, chromeDebugPort: chromeDebugPort, headless: headless, + treeShakeIcons: treeShakeIcons, ).run(); } diff --git a/packages/web_benchmarks/lib/src/runner.dart b/packages/web_benchmarks/lib/src/runner.dart index e47bc2de1b9..66293538d8c 100644 --- a/packages/web_benchmarks/lib/src/runner.dart +++ b/packages/web_benchmarks/lib/src/runner.dart @@ -54,6 +54,7 @@ class BenchmarkServer { required this.benchmarkServerPort, required this.chromeDebugPort, required this.headless, + required this.treeShakeIcons, }); final ProcessManager _processManager = const LocalProcessManager(); @@ -84,6 +85,11 @@ class BenchmarkServer { /// This is useful in environments (e.g. CI) that doesn't have a display. final bool headless; + /// Whether to tree shake icons during the build. + /// + /// When false, '--no-tree-shake-icons' will be passed as a build argument. + final bool treeShakeIcons; + /// Builds and serves the benchmark app, and collects benchmark results. Future run() async { // Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy. @@ -101,6 +107,7 @@ class BenchmarkServer { 'web', '--dart-define=FLUTTER_WEB_ENABLE_PROFILING=true', if (useCanvasKit) '--dart-define=FLUTTER_WEB_USE_SKIA=true', + if (!treeShakeIcons) '--no-tree-shake-icons', '--profile', '-t', entryPoint, diff --git a/packages/web_benchmarks/pubspec.yaml b/packages/web_benchmarks/pubspec.yaml index ee54ff318cd..036c29a6275 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: 0.1.0+7 +version: 0.1.0+8 environment: sdk: ">=2.19.0 <4.0.0" diff --git a/packages/web_benchmarks/testing/test_app/lib/aboutpage.dart b/packages/web_benchmarks/testing/test_app/lib/about_page.dart similarity index 100% rename from packages/web_benchmarks/testing/test_app/lib/aboutpage.dart rename to packages/web_benchmarks/testing/test_app/lib/about_page.dart diff --git a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart b/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart index af5b7bb439f..cf7ef251fb0 100644 --- a/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart +++ b/packages/web_benchmarks/testing/test_app/lib/benchmarks/runner.dart @@ -8,8 +8,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:web_benchmarks/client.dart'; -import '../aboutpage.dart' show backKey; -import '../homepage.dart' show aboutPageKey, textKey; +import '../about_page.dart' show backKey; +import '../home_page.dart' show aboutPageKey, textKey; import '../main.dart'; /// A recorder that measures frame building durations. diff --git a/packages/web_benchmarks/testing/test_app/lib/homepage.dart b/packages/web_benchmarks/testing/test_app/lib/home_page.dart similarity index 100% rename from packages/web_benchmarks/testing/test_app/lib/homepage.dart rename to packages/web_benchmarks/testing/test_app/lib/home_page.dart diff --git a/packages/web_benchmarks/testing/test_app/lib/icon_page.dart b/packages/web_benchmarks/testing/test_app/lib/icon_page.dart new file mode 100644 index 00000000000..fd0da430ee0 --- /dev/null +++ b/packages/web_benchmarks/testing/test_app/lib/icon_page.dart @@ -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 '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 5621621e218..e07fc56ec2a 100644 --- a/packages/web_benchmarks/testing/test_app/lib/main.dart +++ b/packages/web_benchmarks/testing/test_app/lib/main.dart @@ -4,8 +4,9 @@ import 'package:flutter/material.dart'; -import 'aboutpage.dart'; -import 'homepage.dart'; +import 'about_page.dart'; +import 'home_page.dart'; +import 'icon_page.dart'; void main() { runApp(const MyApp()); @@ -26,6 +27,7 @@ class MyApp extends StatelessWidget { routes: { 'home': (_) => const HomePage(title: 'Flutter Demo Home Page'), 'about': (_) => const AboutPage(), + 'icon_generator': (_) => const IconGeneratorPage(), }, ); } diff --git a/packages/web_benchmarks/testing/test_app/pubspec.yaml b/packages/web_benchmarks/testing/test_app/pubspec.yaml index 506615d45da..eb02b1153cd 100644 --- a/packages/web_benchmarks/testing/test_app/pubspec.yaml +++ b/packages/web_benchmarks/testing/test_app/pubspec.yaml @@ -6,10 +6,9 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: ">=2.19.0 <4.0.0" + sdk: '>=2.19.0 <4.0.0' dependencies: - cupertino_icons: ^1.0.5 flutter: sdk: flutter flutter_test: diff --git a/packages/web_benchmarks/testing/web_benchmarks_test.dart b/packages/web_benchmarks/testing/web_benchmarks_test.dart index 3f4db8e1aea..7d092c9eb1e 100644 --- a/packages/web_benchmarks/testing/web_benchmarks_test.dart +++ b/packages/web_benchmarks/testing/web_benchmarks_test.dart @@ -15,6 +15,7 @@ Future main() async { benchmarkAppDirectory: Directory('testing/test_app'), entryPoint: 'lib/benchmarks/runner.dart', useCanvasKit: false, + treeShakeIcons: false, ); for (final String benchmarkName in ['scroll', 'page', 'tap']) { From e02d2a505419ff2d1d67c5f5736f7e851c96a6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= <737941+loic-sharma@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:34:28 -0700 Subject: [PATCH 03/12] [ci] Add build-only Windows Arm64 tests (#5142) Add build-only Windows Arm64 CI tests, mirroring the way we handle multi-arch for macOS. Completes: https://github.com/flutter/flutter/issues/129813 Previous stacked pull requests: * https://github.com/flutter/packages/pull/5133 * https://github.com/flutter/packages/pull/5174 --- .ci.yaml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.ci.yaml b/.ci.yaml index 342630c6ccc..66205fe014b 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -62,6 +62,15 @@ platform_properties: [ {"dependency": "chrome_and_driver", "version": "version:114.0"} ] + windows_arm64: + properties: + dependencies: > + [ + {"dependency": "certs", "version": "version:9563bb"} + ] + device_type: none + os: Windows + cpu: arm64 windows_x64: properties: dependencies: > @@ -1065,6 +1074,20 @@ targets: {"dependency": "vs_build", "version": "version:vs2019"} ] + - name: Windows_arm64 windows-build_all_packages master + recipe: packages/packages + timeout: 30 + bringup: true # https://github.com/flutter/flutter/issues/134083 + properties: + add_recipes_cq: "true" + target_file: windows_build_all_packages.yaml + channel: master + version_file: flutter_master.version + dependencies: > + [ + {"dependency": "vs_build", "version": "version:vs2019"} + ] + - name: Windows_x64 windows-build_all_packages stable recipe: packages/packages timeout: 30 @@ -1078,6 +1101,20 @@ targets: {"dependency": "vs_build", "version": "version:vs2019"} ] + - name: Windows_arm64 windows-build_all_packages stable + recipe: packages/packages + timeout: 30 + bringup: true # https://github.com/flutter/flutter/issues/134083 + properties: + add_recipes_cq: "true" + target_file: windows_build_all_packages.yaml + channel: stable + version_file: flutter_stable.version + dependencies: > + [ + {"dependency": "vs_build", "version": "version:vs2019"} + ] + - name: Windows_x64 repo_tools_tests recipe: packages/packages timeout: 30 From d1fcbabed07a47f9e43083703b916bbcec790ae8 Mon Sep 17 00:00:00 2001 From: Tarrin Neal Date: Fri, 20 Oct 2023 12:28:18 -0700 Subject: [PATCH 04/12] [quick_actions] convert to pigeon (#5159) Converts from direct use of method channels to using Pigeon. Part of https://github.com/flutter/flutter/issues/117844 fixes https://github.com/flutter/flutter/issues/117913 fixes https://github.com/flutter/flutter/issues/117112 --- .../quick_actions_ios/CHANGELOG.md | 4 + .../ios/Runner.xcodeproj/project.pbxproj | 15 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../DefaultShortcutItemParserTests.swift | 67 ------ .../RunnerTests/Mocks/MockMethodChannel.swift | 14 -- .../Mocks/MockShortcutItemParser.swift | 16 -- .../RunnerTests/QuickActionsPluginTests.swift | 188 +++++---------- .../ios/Classes/MethodChannel.swift | 16 -- .../ios/Classes/QuickActionsPlugin.swift | 77 ++++--- .../ios/Classes/ShortcutItemParser.swift | 46 ---- .../ios/Classes/messages.g.swift | 175 ++++++++++++++ .../quick_actions_ios/lib/messages.g.dart | 178 +++++++++++++++ .../lib/quick_actions_ios.dart | 60 ++--- .../quick_actions_ios/pigeons/copyright.txt | 3 + .../quick_actions_ios/pigeons/messages.dart | 44 ++++ .../quick_actions_ios/pubspec.yaml | 3 +- .../test/quick_actions_ios_test.dart | 214 ++++++------------ 17 files changed, 612 insertions(+), 510 deletions(-) delete mode 100644 packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/DefaultShortcutItemParserTests.swift delete mode 100644 packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/Mocks/MockMethodChannel.swift delete mode 100644 packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/Mocks/MockShortcutItemParser.swift delete mode 100644 packages/quick_actions/quick_actions_ios/ios/Classes/MethodChannel.swift delete mode 100644 packages/quick_actions/quick_actions_ios/ios/Classes/ShortcutItemParser.swift create mode 100644 packages/quick_actions/quick_actions_ios/ios/Classes/messages.g.swift create mode 100644 packages/quick_actions/quick_actions_ios/lib/messages.g.dart create mode 100644 packages/quick_actions/quick_actions_ios/pigeons/copyright.txt create mode 100644 packages/quick_actions/quick_actions_ios/pigeons/messages.dart diff --git a/packages/quick_actions/quick_actions_ios/CHANGELOG.md b/packages/quick_actions/quick_actions_ios/CHANGELOG.md index 5272ba930d5..e0321a6056a 100644 --- a/packages/quick_actions/quick_actions_ios/CHANGELOG.md +++ b/packages/quick_actions/quick_actions_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.8 + +* Changes method channels to pigeon. + ## 1.0.7 * Adds pub topics to package metadata. diff --git a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj index 395847ae2de..ed64aa55762 100644 --- a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/project.pbxproj @@ -16,12 +16,9 @@ 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 */; }; - E092A7ED28D10802005C7F67 /* MockMethodChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E092A7EA28D10801005C7F67 /* MockMethodChannel.swift */; }; E092A7EE28D10802005C7F67 /* QuickActionsPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E092A7EB28D10802005C7F67 /* QuickActionsPluginTests.swift */; }; E092A7F128D10890005C7F67 /* MockShortcutItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E092A7F028D10890005C7F67 /* MockShortcutItemProvider.swift */; }; - E092A7F428D110B3005C7F67 /* DefaultShortcutItemParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E092A7F328D110B3005C7F67 /* DefaultShortcutItemParserTests.swift */; }; E092A7F628D128EB005C7F67 /* RunnerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E092A7F528D128EB005C7F67 /* RunnerUITests.swift */; }; - E0A075D529147FE200329BAE /* MockShortcutItemParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0A075D429147FE200329BAE /* MockShortcutItemParser.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -78,12 +75,9 @@ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9D27FE1F0F21D4D47DDA16DE /* 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 = ""; }; C35AD3650AB6BF850E016715 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - E092A7EA28D10801005C7F67 /* MockMethodChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockMethodChannel.swift; sourceTree = ""; }; E092A7EB28D10802005C7F67 /* QuickActionsPluginTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuickActionsPluginTests.swift; sourceTree = ""; }; E092A7F028D10890005C7F67 /* MockShortcutItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockShortcutItemProvider.swift; sourceTree = ""; }; - E092A7F328D110B3005C7F67 /* DefaultShortcutItemParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultShortcutItemParserTests.swift; sourceTree = ""; }; E092A7F528D128EB005C7F67 /* RunnerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerUITests.swift; sourceTree = ""; }; - E0A075D429147FE200329BAE /* MockShortcutItemParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockShortcutItemParser.swift; sourceTree = ""; }; F0609304FBCAEC2289164BD5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -120,7 +114,6 @@ E092A7F228D10908005C7F67 /* Mocks */, 33E20B3626EFCDFC00A4A191 /* Info.plist */, E092A7EB28D10802005C7F67 /* QuickActionsPluginTests.swift */, - E092A7F328D110B3005C7F67 /* DefaultShortcutItemParserTests.swift */, ); path = RunnerTests; sourceTree = ""; @@ -215,9 +208,7 @@ E092A7F228D10908005C7F67 /* Mocks */ = { isa = PBXGroup; children = ( - E092A7EA28D10801005C7F67 /* MockMethodChannel.swift */, E092A7F028D10890005C7F67 /* MockShortcutItemProvider.swift */, - E0A075D429147FE200329BAE /* MockShortcutItemParser.swift */, ); path = Mocks; sourceTree = ""; @@ -289,7 +280,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = "The Flutter Authors"; TargetAttributes = { 33E20B3126EFCDFC00A4A191 = { @@ -364,6 +355,7 @@ files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -435,10 +427,7 @@ buildActionMask = 2147483647; files = ( E092A7EE28D10802005C7F67 /* QuickActionsPluginTests.swift in Sources */, - E092A7ED28D10802005C7F67 /* MockMethodChannel.swift in Sources */, E092A7F128D10890005C7F67 /* MockShortcutItemProvider.swift in Sources */, - E0A075D529147FE200329BAE /* MockShortcutItemParser.swift in Sources */, - E092A7F428D110B3005C7F67 /* DefaultShortcutItemParserTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 1ba2b47c79f..2810c229f3a 100644 --- a/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/quick_actions/quick_actions_ios/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ Void)? = nil - func invokeMethod(_ method: String, arguments: Any?) { - invokeMethodStub?(method, arguments) - } -} diff --git a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/Mocks/MockShortcutItemParser.swift b/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/Mocks/MockShortcutItemParser.swift deleted file mode 100644 index 3b5a0965395..00000000000 --- a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/Mocks/MockShortcutItemParser.swift +++ /dev/null @@ -1,16 +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 Foundation - -@testable import quick_actions_ios - -final class MockShortcutItemParser: ShortcutItemParser { - - var parseShortcutItemsStub: ((_ items: [[String: Any]]) -> [UIApplicationShortcutItem])? = nil - - func parseShortcutItems(_ items: [[String: Any]]) -> [UIApplicationShortcutItem] { - return parseShortcutItemsStub?(items) ?? [] - } -} diff --git a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/QuickActionsPluginTests.swift b/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/QuickActionsPluginTests.swift index 268a89ba5a5..f0dff1650b7 100644 --- a/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/QuickActionsPluginTests.swift +++ b/packages/quick_actions/quick_actions_ios/example/ios/RunnerTests/QuickActionsPluginTests.swift @@ -7,14 +7,27 @@ import XCTest @testable import quick_actions_ios +class MockFlutterApi: IOSQuickActionsFlutterApiProtocol { + /// Method to allow for async testing. + var launchActionCallback: ((String) -> Void)? = nil + + func launchAction( + action actionArg: String, completion: @escaping (Result) -> Void + ) { + self.launchActionCallback?(actionArg) + completion(.success(Void())) + } +} + class QuickActionsPluginTests: XCTestCase { func testHandleMethodCall_setShortcutItems() { - let rawItem = [ - "type": "SearchTheThing", - "localizedTitle": "Search the thing", - "icon": "search_the_thing.png", - ] + let rawItem = ShortcutItemMessage( + type: "SearchTheThing", + localizedTitle: "Search the thing", + icon: "search_the_thing.png" + ) + let item = UIApplicationShortcutItem( type: "SearchTheThing", localizedTitle: "Search the thing", @@ -22,32 +35,15 @@ class QuickActionsPluginTests: XCTestCase { icon: UIApplicationShortcutIcon(templateImageName: "search_the_thing.png"), userInfo: nil) - let call = FlutterMethodCall(methodName: "setShortcutItems", arguments: [rawItem]) - - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) - - let parseShortcutItemsExpectation = expectation( - description: "parseShortcutItems must be called.") - mockShortcutItemParser.parseShortcutItemsStub = { items in - XCTAssertEqual(items as? [[String: String]], [rawItem]) - parseShortcutItemsExpectation.fulfill() - return [item] - } + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) - let resultExpectation = expectation(description: "result block must be called.") - plugin.handle(call) { result in - XCTAssertNil(result, "result block must be called with nil.") - resultExpectation.fulfill() - } + plugin.setShortcutItems(itemsList: [rawItem]) XCTAssertEqual(mockShortcutItemProvider.shortcutItems, [item], "Must set shortcut items.") - waitForExpectations(timeout: 1) } func testHandleMethodCall_clearShortcutItems() { @@ -58,82 +54,28 @@ class QuickActionsPluginTests: XCTestCase { icon: UIApplicationShortcutIcon(templateImageName: "search_the_thing.png"), userInfo: nil) - let call = FlutterMethodCall(methodName: "clearShortcutItems", arguments: nil) - let mockChannel = MockMethodChannel() - let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() - - mockShortcutItemProvider.shortcutItems = [item] - - let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) - - let resultExpectation = expectation(description: "result block must be called.") - plugin.handle(call) { result in - XCTAssertNil(result, "result block must be called with nil.") - resultExpectation.fulfill() - } - - XCTAssertEqual(mockShortcutItemProvider.shortcutItems, [], "Must clear shortcut items.") - waitForExpectations(timeout: 1) - } - - func testHandleMethodCall_getLaunchAction() { - let call = FlutterMethodCall(methodName: "getLaunchAction", arguments: nil) - - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) - - let resultExpectation = expectation(description: "result block must be called.") - plugin.handle(call) { result in - XCTAssertNil(result, "result block must be called with nil.") - resultExpectation.fulfill() - } - - waitForExpectations(timeout: 1) - } - - func testHandleMethodCall_nonExistMethods() { - let call = FlutterMethodCall(methodName: "nonExist", arguments: nil) - - let mockChannel = MockMethodChannel() - let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) - let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + mockShortcutItemProvider.shortcutItems = [item] - let resultExpectation = expectation(description: "result block must be called.") + plugin.clearShortcutItems() - plugin.handle(call) { result in - XCTAssertEqual( - result as? NSObject, FlutterMethodNotImplemented, - "result block must be called with FlutterMethodNotImplemented") - resultExpectation.fulfill() - } + XCTAssertEqual(mockShortcutItemProvider.shortcutItems, [], "Must clear shortcut items.") - waitForExpectations(timeout: 1) } func testApplicationPerformActionForShortcutItem() { - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let item = UIApplicationShortcutItem( type: "SearchTheThing", @@ -143,30 +85,29 @@ class QuickActionsPluginTests: XCTestCase { userInfo: nil) let invokeMethodExpectation = expectation(description: "invokeMethod must be called.") - mockChannel.invokeMethodStub = { method, arguments in - XCTAssertEqual(method, "launch") - XCTAssertEqual(arguments as? String, item.type) + flutterApi.launchActionCallback = { aString in + XCTAssertEqual(aString, item.type) invokeMethodExpectation.fulfill() } let actionResult = plugin.application( UIApplication.shared, performActionFor: item - ) { success in /* no-op */ } + ) { success in + // noop + } XCTAssert(actionResult, "performActionForShortcutItem must return true.") waitForExpectations(timeout: 1) } func testApplicationDidFinishLaunchingWithOptions_launchWithShortcut() { - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let item = UIApplicationShortcutItem( type: "SearchTheThing", @@ -183,14 +124,12 @@ class QuickActionsPluginTests: XCTestCase { } func testApplicationDidFinishLaunchingWithOptions_launchWithoutShortcut() { - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let launchResult = plugin.application(UIApplication.shared, didFinishLaunchingWithOptions: [:]) XCTAssert( @@ -198,18 +137,12 @@ class QuickActionsPluginTests: XCTestCase { } func testApplicationDidBecomeActive_launchWithoutShortcut() { - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) - - mockChannel.invokeMethodStub = { _, _ in - XCTFail("invokeMethod should not be called if launch without shortcut.") - } + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let launchResult = plugin.application(UIApplication.shared, didFinishLaunchingWithOptions: [:]) XCTAssert( @@ -226,19 +159,16 @@ class QuickActionsPluginTests: XCTestCase { icon: UIApplicationShortcutIcon(templateImageName: "search_the_thing.png"), userInfo: nil) - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let invokeMethodExpectation = expectation(description: "invokeMethod must be called.") - mockChannel.invokeMethodStub = { method, arguments in - XCTAssertEqual(method, "launch") - XCTAssertEqual(arguments as? String, item.type) + flutterApi.launchActionCallback = { aString in + XCTAssertEqual(aString, item.type) invokeMethodExpectation.fulfill() } @@ -261,20 +191,19 @@ class QuickActionsPluginTests: XCTestCase { icon: UIApplicationShortcutIcon(templateImageName: "search_the_thing.png"), userInfo: nil) - let mockChannel = MockMethodChannel() + let flutterApi: MockFlutterApi = MockFlutterApi() let mockShortcutItemProvider = MockShortcutItemProvider() - let mockShortcutItemParser = MockShortcutItemParser() let plugin = QuickActionsPlugin( - channel: mockChannel, - shortcutItemProvider: mockShortcutItemProvider, - shortcutItemParser: mockShortcutItemParser) + flutterApi: flutterApi, + shortcutItemProvider: mockShortcutItemProvider) let invokeMethodExpectation = expectation(description: "invokeMethod must be called.") - var invokeMehtodCount = 0 - mockChannel.invokeMethodStub = { method, arguments in - invokeMehtodCount += 1 + var invokeMethodCount = 0 + flutterApi.launchActionCallback = { aString in + XCTAssertEqual(aString, item.type) + invokeMethodCount += 1 invokeMethodExpectation.fulfill() } @@ -288,7 +217,6 @@ class QuickActionsPluginTests: XCTestCase { plugin.applicationDidBecomeActive(UIApplication.shared) waitForExpectations(timeout: 1) - XCTAssertEqual(invokeMehtodCount, 1, "shortcut should only be handled once per launch.") + XCTAssertEqual(invokeMethodCount, 1, "shortcut should only be handled once per launch.") } - } diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/MethodChannel.swift b/packages/quick_actions/quick_actions_ios/ios/Classes/MethodChannel.swift deleted file mode 100644 index 5d52790dd4b..00000000000 --- a/packages/quick_actions/quick_actions_ios/ios/Classes/MethodChannel.swift +++ /dev/null @@ -1,16 +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 - -/// A channel for platform code to communicate with the Dart code. -protocol MethodChannel { - /// Invokes a method in Dart code. - /// - Parameter method the method name. - /// - Parameter arguments the method arguments. - func invokeMethod(_ method: String, arguments: Any?) -} - -/// A default implementation of the `MethodChannel` protocol. -extension FlutterMethodChannel: MethodChannel {} diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.swift b/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.swift index 8522c5ff528..dc8ffb812f3 100644 --- a/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.swift +++ b/packages/quick_actions/quick_actions_ios/ios/Classes/QuickActionsPlugin.swift @@ -4,48 +4,36 @@ import Flutter -public final class QuickActionsPlugin: NSObject, FlutterPlugin { +public final class QuickActionsPlugin: NSObject, FlutterPlugin, IOSQuickActionsApi { public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel( - name: "plugins.flutter.io/quick_actions_ios", - binaryMessenger: registrar.messenger()) - let instance = QuickActionsPlugin(channel: channel) - registrar.addMethodCallDelegate(instance, channel: channel) + let messenger = registrar.messenger() + let flutterApi = IOSQuickActionsFlutterApi(binaryMessenger: messenger) + let instance = QuickActionsPlugin(flutterApi: flutterApi) + IOSQuickActionsApiSetup.setUp(binaryMessenger: messenger, api: instance) registrar.addApplicationDelegate(instance) } - private let channel: MethodChannel private let shortcutItemProvider: ShortcutItemProviding - private let shortcutItemParser: ShortcutItemParser + private let flutterApi: IOSQuickActionsFlutterApiProtocol /// The type of the shortcut item selected when launching the app. private var launchingShortcutType: String? = nil init( - channel: MethodChannel, - shortcutItemProvider: ShortcutItemProviding = UIApplication.shared, - shortcutItemParser: ShortcutItemParser = DefaultShortcutItemParser() + flutterApi: IOSQuickActionsFlutterApiProtocol, + shortcutItemProvider: ShortcutItemProviding = UIApplication.shared ) { - self.channel = channel + self.flutterApi = flutterApi self.shortcutItemProvider = shortcutItemProvider - self.shortcutItemParser = shortcutItemParser } - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "setShortcutItems": - // `arguments` must be an array of dictionaries - let items = call.arguments as! [[String: Any]] - shortcutItemProvider.shortcutItems = shortcutItemParser.parseShortcutItems(items) - result(nil) - case "clearShortcutItems": - shortcutItemProvider.shortcutItems = [] - result(nil) - case "getLaunchAction": - result(nil) - case _: - result(FlutterMethodNotImplemented) - } + func setShortcutItems(itemsList: [ShortcutItemMessage]) { + shortcutItemProvider.shortcutItems = + convertShortcutItemMessageListToUIApplicationShortcutItemList(itemsList) + } + + func clearShortcutItems() { + shortcutItemProvider.shortcutItems = [] } public func application( @@ -84,8 +72,37 @@ public final class QuickActionsPlugin: NSObject, FlutterPlugin { } } - private func handleShortcut(_ shortcut: String) { - channel.invokeMethod("launch", arguments: shortcut) + func handleShortcut(_ shortcut: String) { + flutterApi.launchAction(action: shortcut) { _ in + // noop + } + } + + private func convertShortcutItemMessageListToUIApplicationShortcutItemList( + _ items: [ShortcutItemMessage] + ) -> [UIApplicationShortcutItem] { + return items.compactMap { convertShortcutItemMessageToUIApplicationShortcutItem(with: $0) } } + private func convertShortcutItemMessageToUIApplicationShortcutItem( + with shortcut: ShortcutItemMessage + ) + -> UIApplicationShortcutItem? + { + + let type = shortcut.type + let localizedTitle = shortcut.localizedTitle + + let icon = (shortcut.icon).map { + UIApplicationShortcutIcon(templateImageName: $0) + } + + // type and localizedTitle are required. + return UIApplicationShortcutItem( + type: type, + localizedTitle: localizedTitle, + localizedSubtitle: nil, + icon: icon, + userInfo: nil) + } } diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/ShortcutItemParser.swift b/packages/quick_actions/quick_actions_ios/ios/Classes/ShortcutItemParser.swift deleted file mode 100644 index 0945b4a386f..00000000000 --- a/packages/quick_actions/quick_actions_ios/ios/Classes/ShortcutItemParser.swift +++ /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 UIKit - -/// A parser that parses an array of raw shortcut items. -protocol ShortcutItemParser { - - /// Parses an array of raw shortcut items into an array of UIApplicationShortcutItems - /// - /// - Parameter items an array of raw shortcut items to be parsed. - /// - Returns an array of parsed shortcut items to be set. - /// - func parseShortcutItems(_ items: [[String: Any]]) -> [UIApplicationShortcutItem] -} - -/// A default implementation of the `ShortcutItemParser` protocol. -final class DefaultShortcutItemParser: ShortcutItemParser { - - func parseShortcutItems(_ items: [[String: Any]]) -> [UIApplicationShortcutItem] { - return items.compactMap { deserializeShortcutItem(with: $0) } - } - - private func deserializeShortcutItem(with serialized: [String: Any]) -> UIApplicationShortcutItem? - { - guard - let type = serialized["type"] as? String, - let localizedTitle = serialized["localizedTitle"] as? String - else { - return nil - } - - let icon = (serialized["icon"] as? String).map { - UIApplicationShortcutIcon(templateImageName: $0) - } - - // type and localizedTitle are required. - return UIApplicationShortcutItem( - type: type, - localizedTitle: localizedTitle, - localizedSubtitle: nil, - icon: icon, - userInfo: nil) - } -} diff --git a/packages/quick_actions/quick_actions_ios/ios/Classes/messages.g.swift b/packages/quick_actions/quick_actions_ios/ios/Classes/messages.g.swift new file mode 100644 index 00000000000..0dec7a61994 --- /dev/null +++ b/packages/quick_actions/quick_actions_ios/ios/Classes/messages.g.swift @@ -0,0 +1,175 @@ +// Copyright 2013 The Flutter 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 (v12.0.1), 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 + +extension FlutterError: Error {} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)" + ] +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +/// Home screen quick-action shortcut item. +/// +/// Generated class from Pigeon that represents data sent in messages. +struct ShortcutItemMessage { + /// The identifier of this item; should be unique within the app. + var type: String + /// Localized title of the item. + var localizedTitle: String + /// Name of native resource to be displayed as the icon for this item. + var icon: String? = nil + + static func fromList(_ list: [Any?]) -> ShortcutItemMessage? { + let type = list[0] as! String + let localizedTitle = list[1] as! String + let icon: String? = nilOrValue(list[2]) + + return ShortcutItemMessage( + type: type, + localizedTitle: localizedTitle, + icon: icon + ) + } + func toList() -> [Any?] { + return [ + type, + localizedTitle, + icon, + ] + } +} +private class IOSQuickActionsApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return ShortcutItemMessage.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class IOSQuickActionsApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? ShortcutItemMessage { + super.writeByte(128) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class IOSQuickActionsApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return IOSQuickActionsApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return IOSQuickActionsApiCodecWriter(data: data) + } +} + +class IOSQuickActionsApiCodec: FlutterStandardMessageCodec { + static let shared = IOSQuickActionsApiCodec(readerWriter: IOSQuickActionsApiCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol IOSQuickActionsApi { + /// Sets the dynamic shortcuts for the app. + func setShortcutItems(itemsList: [ShortcutItemMessage]) throws + /// Removes all dynamic shortcuts. + func clearShortcutItems() throws +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class IOSQuickActionsApiSetup { + /// The codec used by IOSQuickActionsApi. + static var codec: FlutterStandardMessageCodec { IOSQuickActionsApiCodec.shared } + /// Sets up an instance of `IOSQuickActionsApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: IOSQuickActionsApi?) { + /// Sets the dynamic shortcuts for the app. + let setShortcutItemsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsApi.setShortcutItems", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + setShortcutItemsChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let itemsListArg = args[0] as! [ShortcutItemMessage] + do { + try api.setShortcutItems(itemsList: itemsListArg) + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + setShortcutItemsChannel.setMessageHandler(nil) + } + /// Removes all dynamic shortcuts. + let clearShortcutItemsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsApi.clearShortcutItems", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + clearShortcutItemsChannel.setMessageHandler { _, reply in + do { + try api.clearShortcutItems() + reply(wrapResult(nil)) + } catch { + reply(wrapError(error)) + } + } + } else { + clearShortcutItemsChannel.setMessageHandler(nil) + } + } +} +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol IOSQuickActionsFlutterApiProtocol { + /// Sends a string representing a shortcut from the native platform to the app. + func launchAction(action actionArg: String, completion: @escaping (Result) -> Void) +} +class IOSQuickActionsFlutterApi: IOSQuickActionsFlutterApiProtocol { + private let binaryMessenger: FlutterBinaryMessenger + init(binaryMessenger: FlutterBinaryMessenger){ + self.binaryMessenger = binaryMessenger + } + /// Sends a string representing a shortcut from the native platform to the app. + func launchAction(action actionArg: String, completion: @escaping (Result) -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsFlutterApi.launchAction", binaryMessenger: binaryMessenger) + channel.sendMessage([actionArg] as [Any?]) { _ in + completion(.success(Void())) + } + } +} diff --git a/packages/quick_actions/quick_actions_ios/lib/messages.g.dart b/packages/quick_actions/quick_actions_ios/lib/messages.g.dart new file mode 100644 index 00000000000..f1d64464772 --- /dev/null +++ b/packages/quick_actions/quick_actions_ios/lib/messages.g.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. +// Autogenerated from Pigeon (v12.0.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 + +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'; + +List wrapResponse( + {Object? result, PlatformException? error, bool empty = false}) { + if (empty) { + return []; + } + if (error == null) { + return [result]; + } + return [error.code, error.message, error.details]; +} + +/// Home screen quick-action shortcut item. +class ShortcutItemMessage { + ShortcutItemMessage({ + required this.type, + required this.localizedTitle, + this.icon, + }); + + /// The identifier of this item; should be unique within the app. + String type; + + /// Localized title of the item. + String localizedTitle; + + /// Name of native resource to be displayed as the icon for this item. + String? icon; + + Object encode() { + return [ + type, + localizedTitle, + icon, + ]; + } + + static ShortcutItemMessage decode(Object result) { + result as List; + return ShortcutItemMessage( + type: result[0]! as String, + localizedTitle: result[1]! as String, + icon: result[2] as String?, + ); + } +} + +class _IOSQuickActionsApiCodec extends StandardMessageCodec { + const _IOSQuickActionsApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is ShortcutItemMessage) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return ShortcutItemMessage.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class IOSQuickActionsApi { + /// Constructor for [IOSQuickActionsApi]. 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. + IOSQuickActionsApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _IOSQuickActionsApiCodec(); + + /// Sets the dynamic shortcuts for the app. + Future setShortcutItems( + List arg_itemsList) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsApi.setShortcutItems', + codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_itemsList]) 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; + } + } + + /// Removes all dynamic shortcuts. + Future clearShortcutItems() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsApi.clearShortcutItems', + 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 { + return; + } + } +} + +abstract class IOSQuickActionsFlutterApi { + static const MessageCodec codec = StandardMessageCodec(); + + /// Sends a string representing a shortcut from the native platform to the app. + void launchAction(String action); + + static void setup(IOSQuickActionsFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsFlutterApi.launchAction', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsFlutterApi.launchAction was null.'); + final List args = (message as List?)!; + final String? arg_action = (args[0] as String?); + assert(arg_action != null, + 'Argument for dev.flutter.pigeon.quick_actions_ios.IOSQuickActionsFlutterApi.launchAction was null, expected non-null String.'); + try { + api.launchAction(arg_action!); + 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/quick_actions/quick_actions_ios/lib/quick_actions_ios.dart b/packages/quick_actions/quick_actions_ios/lib/quick_actions_ios.dart index d19c9ee371b..235591774c5 100644 --- a/packages/quick_actions/quick_actions_ios/lib/quick_actions_ios.dart +++ b/packages/quick_actions/quick_actions_ios/lib/quick_actions_ios.dart @@ -3,54 +3,58 @@ // found in the LICENSE file. import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:quick_actions_platform_interface/quick_actions_platform_interface.dart'; +import 'messages.g.dart'; + export 'package:quick_actions_platform_interface/types/types.dart'; -const MethodChannel _channel = - MethodChannel('plugins.flutter.io/quick_actions_ios'); +late QuickActionHandler _handler; /// An implementation of [QuickActionsPlatform] for iOS. class QuickActionsIos extends QuickActionsPlatform { + /// Creates a new plugin implementation instance. + QuickActionsIos({ + @visibleForTesting IOSQuickActionsApi? api, + }) : _hostApi = api ?? IOSQuickActionsApi(); + + final IOSQuickActionsApi _hostApi; + /// Registers this class as the default instance of [QuickActionsPlatform]. static void registerWith() { QuickActionsPlatform.instance = QuickActionsIos(); } - /// The MethodChannel that is being used by this implementation of the plugin. - @visibleForTesting - MethodChannel get channel => _channel; - @override Future initialize(QuickActionHandler handler) async { - channel.setMethodCallHandler((MethodCall call) async { - assert(call.method == 'launch'); - handler(call.arguments as String); - }); - final String? action = - await channel.invokeMethod('getLaunchAction'); - if (action != null) { - handler(action); - } + final _QuickActionHandlerApi quickActionsHandlerApi = + _QuickActionHandlerApi(); + IOSQuickActionsFlutterApi.setup(quickActionsHandlerApi); + _handler = handler; } @override Future setShortcutItems(List items) async { - final List> itemsList = - items.map(_serializeItem).toList(); - await channel.invokeMethod('setShortcutItems', itemsList); + await _hostApi.setShortcutItems( + items.map(_shortcutItemToShortcutItemMessage).toList(), + ); } @override - Future clearShortcutItems() => - channel.invokeMethod('clearShortcutItems'); - - Map _serializeItem(ShortcutItem item) { - return { - 'type': item.type, - 'localizedTitle': item.localizedTitle, - 'icon': item.icon, - }; + Future clearShortcutItems() => _hostApi.clearShortcutItems(); + + ShortcutItemMessage _shortcutItemToShortcutItemMessage(ShortcutItem item) { + return ShortcutItemMessage( + type: item.type, + localizedTitle: item.localizedTitle, + icon: item.icon, + ); + } +} + +class _QuickActionHandlerApi extends IOSQuickActionsFlutterApi { + @override + void launchAction(String action) { + _handler(action); } } diff --git a/packages/quick_actions/quick_actions_ios/pigeons/copyright.txt b/packages/quick_actions/quick_actions_ios/pigeons/copyright.txt new file mode 100644 index 00000000000..1236b63caf3 --- /dev/null +++ b/packages/quick_actions/quick_actions_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/quick_actions/quick_actions_ios/pigeons/messages.dart b/packages/quick_actions/quick_actions_ios/pigeons/messages.dart new file mode 100644 index 00000000000..553d8552cf7 --- /dev/null +++ b/packages/quick_actions/quick_actions_ios/pigeons/messages.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:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/messages.g.dart', + swiftOut: 'ios/Classes/messages.g.swift', + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// Home screen quick-action shortcut item. +class ShortcutItemMessage { + ShortcutItemMessage( + this.type, + this.localizedTitle, + this.icon, + ); + + /// The identifier of this item; should be unique within the app. + String type; + + /// Localized title of the item. + String localizedTitle; + + /// Name of native resource to be displayed as the icon for this item. + String? icon; +} + +@HostApi() +abstract class IOSQuickActionsApi { + /// Sets the dynamic shortcuts for the app. + void setShortcutItems(List itemsList); + + /// Removes all dynamic shortcuts. + void clearShortcutItems(); +} + +@FlutterApi() +abstract class IOSQuickActionsFlutterApi { + /// Sends a string representing a shortcut from the native platform to the app. + void launchAction(String action); +} diff --git a/packages/quick_actions/quick_actions_ios/pubspec.yaml b/packages/quick_actions/quick_actions_ios/pubspec.yaml index b7e31d8646b..3be66b4f886 100644 --- a/packages/quick_actions/quick_actions_ios/pubspec.yaml +++ b/packages/quick_actions/quick_actions_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: quick_actions_ios description: An implementation for the iOS platform of the Flutter `quick_actions` plugin. repository: https://github.com/flutter/packages/tree/main/packages/quick_actions/quick_actions_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 1.0.7 +version: 1.0.8 environment: sdk: ">=2.19.0 <4.0.0" @@ -26,6 +26,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter + pigeon: ^12.0.1 plugin_platform_interface: ^2.1.2 topics: diff --git a/packages/quick_actions/quick_actions_ios/test/quick_actions_ios_test.dart b/packages/quick_actions/quick_actions_ios/test/quick_actions_ios_test.dart index d2b062fff22..c2e281a1a14 100644 --- a/packages/quick_actions/quick_actions_ios/test/quick_actions_ios_test.dart +++ b/packages/quick_actions/quick_actions_ios/test/quick_actions_ios_test.dart @@ -2,171 +2,89 @@ // 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:quick_actions_ios/messages.g.dart'; import 'package:quick_actions_ios/quick_actions_ios.dart'; import 'package:quick_actions_platform_interface/quick_actions_platform_interface.dart'; +const String LAUNCH_ACTION_STRING = 'aString'; + void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group('$QuickActionsIos', () { - late List log; + final _FakeQuickActionsApi api = _FakeQuickActionsApi(); + final QuickActionsIos quickActions = QuickActionsIos(api: api); - setUp(() { - log = []; - }); - - QuickActionsIos buildQuickActionsPlugin() { - final QuickActionsIos quickActions = QuickActionsIos(); - _ambiguate(TestDefaultBinaryMessengerBinding.instance)! - .defaultBinaryMessenger - .setMockMethodCallHandler(quickActions.channel, - (MethodCall methodCall) async { - log.add(methodCall); - return ''; - }); - - return quickActions; - } + test('registerWith() registers correct instance', () { + QuickActionsIos.registerWith(); + expect(QuickActionsPlatform.instance, isA()); + }); - test('registerWith() registers correct instance', () { - QuickActionsIos.registerWith(); - expect(QuickActionsPlatform.instance, isA()); + group('#initialize', () { + test('initialize', () { + expect(quickActions.initialize((_) {}), completes); }); + }); - group('#initialize', () { - test('passes getLaunchAction on launch method', () { - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - quickActions.initialize((String type) {}); - - expect( - log, - [ - isMethodCall('getLaunchAction', arguments: null), - ], - ); - }); - - test('initialize', () async { - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - final Completer quickActionsHandler = Completer(); - await quickActions - .initialize((_) => quickActionsHandler.complete(true)); - expect( - log, - [ - isMethodCall('getLaunchAction', arguments: null), - ], - ); - log.clear(); - - expect(quickActionsHandler.future, completion(isTrue)); - }); - }); + test('setShortcutItems', () async { + await quickActions.initialize((String type) {}); + const ShortcutItem item = + ShortcutItem(type: 'test', localizedTitle: 'title', icon: 'icon.svg'); + await quickActions.setShortcutItems([item]); - group('#setShortCutItems', () { - test('passes shortcutItem through channel', () { - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - quickActions.initialize((String type) {}); - quickActions.setShortcutItems([ - const ShortcutItem( - type: 'test', localizedTitle: 'title', icon: 'icon.svg') - ]); - - expect( - log, - [ - isMethodCall('getLaunchAction', arguments: null), - isMethodCall('setShortcutItems', arguments: >[ - { - 'type': 'test', - 'localizedTitle': 'title', - 'icon': 'icon.svg', - } - ]), - ], - ); - }); - - test('setShortcutItems with demo data', () async { - const String type = 'type'; - const String localizedTitle = 'localizedTitle'; - const String icon = 'icon'; - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - await quickActions.setShortcutItems( - const [ - ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon) - ], - ); - expect( - log, - [ - isMethodCall( - 'setShortcutItems', - arguments: >[ - { - 'type': type, - 'localizedTitle': localizedTitle, - 'icon': icon, - } - ], - ), - ], - ); - log.clear(); - }); - }); + expect(api.items.first.type, item.type); + expect(api.items.first.localizedTitle, item.localizedTitle); + expect(api.items.first.icon, item.icon); + }); - group('#clearShortCutItems', () { - test('send clearShortcutItems through channel', () { - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - quickActions.initialize((String type) {}); - quickActions.clearShortcutItems(); - - expect( - log, - [ - isMethodCall('getLaunchAction', arguments: null), - isMethodCall('clearShortcutItems', arguments: null), - ], - ); - }); - - test('clearShortcutItems', () { - final QuickActionsIos quickActions = buildQuickActionsPlugin(); - quickActions.clearShortcutItems(); - expect( - log, - [ - isMethodCall('clearShortcutItems', arguments: null), - ], - ); - log.clear(); - }); - }); + test('clearShortCutItems', () { + quickActions.initialize((String type) {}); + const ShortcutItem item = + ShortcutItem(type: 'test', localizedTitle: 'title', icon: 'icon.svg'); + quickActions.setShortcutItems([item]); + quickActions.clearShortcutItems(); + + expect(api.items.isEmpty, true); }); - group('$ShortcutItem', () { - test('Shortcut item can be constructed', () { - const String type = 'type'; - const String localizedTitle = 'title'; - const String icon = 'foo'; + test('Shortcut item can be constructed', () { + const String type = 'type'; + const String localizedTitle = 'title'; + const String icon = 'foo'; - const ShortcutItem item = - ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon); + const ShortcutItem item = + ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon); - expect(item.type, type); - expect(item.localizedTitle, localizedTitle); - expect(item.icon, icon); - }); + expect(item.type, type); + expect(item.localizedTitle, localizedTitle); + expect(item.icon, icon); }); } -/// This allows a value of type T or T? to be treated as a value of type T?. -/// -/// We use this so that APIs that have become non-nullable can still be used -/// with `!` and `?` on the stable branch. -T? _ambiguate(T? value) => value; +class _FakeQuickActionsApi implements IOSQuickActionsApi { + List items = []; + bool getLaunchActionCalled = false; + + @override + Future clearShortcutItems() async { + items = []; + return; + } + + @override + Future setShortcutItems(List itemsList) async { + await clearShortcutItems(); + for (final ShortcutItemMessage? element in itemsList) { + items.add(shortcutItemMessageToShortcutItem(element!)); + } + } +} + +/// Conversion tool to change [ShortcutItemMessage] back to [ShortcutItem] +ShortcutItem shortcutItemMessageToShortcutItem(ShortcutItemMessage item) { + return ShortcutItem( + type: item.type, + localizedTitle: item.localizedTitle, + icon: item.icon, + ); +} From e4c7420800377882012349a2240bbf0fa72ce43a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:03:57 +0000 Subject: [PATCH 05/12] [in_app_pur]: Bump org.json:json from 20230618 to 20231013 in /packages/in_app_purchase/in_app_purchase_android/android (#5150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.json:json](https://github.com/douglascrockford/JSON-java) from 20230618 to 20231013.
Release notes

Sourced from org.json:json's releases.

20231013

Pull Request Description
#793 Reverted #761
#792 update the docs for release 20231013
#783 optLong vs getLong inconsistencies
#782 Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows
#779 add validity check for JSONObject constructors
#778 Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows
#776 Update [JUnit to version 4.13.2
#774 Removing unneeded synchronization
#773 Add optJSONArray method to JSONObject with a default value
#772 Disallow nested objects and arrays as keys in objects
#779 Unit test cleanup
#769 Addressed Java 17 compile warnings
#764 Update CodeQL action version
#761 Add module-info
#759 JSON parsing should detect embedded 
#753 Updated new object methods
#752 Fixes possible unit test bug when compiling/testing on Windows
Changelog

Sourced from org.json:json's changelog.

20231013 First release with minimum Java version 1.8. Recent commits, including fixes for CVE-2023-5072.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.json:json&package-manager=gradle&previous-version=20230618&new-version=20231013)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .../in_app_purchase_android/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cef22be3a4a..f658a58896b 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 @@ -63,7 +63,7 @@ dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.22")) implementation 'com.android.billingclient:billing:6.0.1' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.json:json:20230618' + testImplementation 'org.json:json:20231013' testImplementation 'org.mockito:mockito-core:5.4.0' androidTestImplementation 'androidx.test:runner:1.4.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' From 2181c4f29d6bbadcafe4872509eb4d912c57f923 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:10:14 +0000 Subject: [PATCH 06/12] [in_app_pur]: Bump org.json:json from 20230618 to 20231013 in /packages/in_app_purchase/in_app_purchase_android/example/android/app (#5149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.json:json](https://github.com/douglascrockford/JSON-java) from 20230618 to 20231013.
Release notes

Sourced from org.json:json's releases.

20231013

Pull Request Description
#793 Reverted #761
#792 update the docs for release 20231013
#783 optLong vs getLong inconsistencies
#782 Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows
#779 add validity check for JSONObject constructors
#778 Fix XMLTest.testIndentComplicatedJsonObjectWithArrayAndWithConfig() for Windows
#776 Update [JUnit to version 4.13.2
#774 Removing unneeded synchronization
#773 Add optJSONArray method to JSONObject with a default value
#772 Disallow nested objects and arrays as keys in objects
#779 Unit test cleanup
#769 Addressed Java 17 compile warnings
#764 Update CodeQL action version
#761 Add module-info
#759 JSON parsing should detect embedded 
#753 Updated new object methods
#752 Fixes possible unit test bug when compiling/testing on Windows
Changelog

Sourced from org.json:json's changelog.

20231013 First release with minimum Java version 1.8. Recent commits, including fixes for CVE-2023-5072.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.json:json&package-manager=gradle&previous-version=20230618&new-version=20231013)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .../in_app_purchase_android/example/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase_android/example/android/app/build.gradle b/packages/in_app_purchase/in_app_purchase_android/example/android/app/build.gradle index c25f7fd1698..dd0c26c8a49 100644 --- a/packages/in_app_purchase/in_app_purchase_android/example/android/app/build.gradle +++ b/packages/in_app_purchase/in_app_purchase_android/example/android/app/build.gradle @@ -110,7 +110,7 @@ dependencies { implementation 'com.android.billingclient:billing:5.0.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.1.1' - testImplementation 'org.json:json:20230618' + testImplementation 'org.json:json:20231013' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } From 0fbf36819a8f0ef2e6df43f363e978dea69586cd Mon Sep 17 00:00:00 2001 From: Mairramer <50643541+Mairramer@users.noreply.github.com> Date: Fri, 20 Oct 2023 21:32:13 -0300 Subject: [PATCH 07/12] [ios_platform_images] migrate objC to swift (#4847) `ios_platform_images` part of https://github.com/flutter/flutter/issues/119101 Migrate ios_platform_images to Swift. --- packages/ios_platform_images/AUTHORS | 1 + packages/ios_platform_images/CHANGELOG.md | 4 + packages/ios_platform_images/README.md | 12 +- .../ios/Runner.xcodeproj/project.pbxproj | 113 +++++++----- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 14 ++ .../example/ios/Runner/AppDelegate.swift | 2 +- .../ios/RunnerTests/IosPlatformImagesTests.m | 18 -- .../RunnerTests/IosPlatformImagesTests.swift | 48 ++++++ .../ios/Classes/IosPlatformImagesPlugin.h | 12 -- .../ios/Classes/IosPlatformImagesPlugin.m | 40 ----- .../ios/Classes/IosPlatformImagesPlugin.swift | 38 ++++ .../ios/Classes/UIImage+ios_platform_images.h | 27 --- .../ios/Classes/UIImage+ios_platform_images.m | 25 --- .../Classes/UIImageIosPlatformImages.swift | 41 +++++ .../ios/Classes/messages.g.h | 47 ----- .../ios/Classes/messages.g.m | 163 ------------------ .../ios/Classes/messages.g.swift | 162 +++++++++++++++++ .../ios/ios_platform_images.podspec | 9 +- .../lib/ios_platform_images.dart | 2 +- .../ios_platform_images/pigeons/messages.dart | 6 +- packages/ios_platform_images/pubspec.yaml | 2 +- 22 files changed, 402 insertions(+), 392 deletions(-) create mode 100644 packages/ios_platform_images/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 packages/ios_platform_images/example/ios/RunnerTests/IosPlatformImagesTests.m create mode 100644 packages/ios_platform_images/example/ios/RunnerTests/IosPlatformImagesTests.swift delete mode 100644 packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.h delete mode 100644 packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m create mode 100644 packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.swift delete mode 100644 packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.h delete mode 100644 packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.m create mode 100644 packages/ios_platform_images/ios/Classes/UIImageIosPlatformImages.swift delete mode 100644 packages/ios_platform_images/ios/Classes/messages.g.h delete mode 100644 packages/ios_platform_images/ios/Classes/messages.g.m create mode 100644 packages/ios_platform_images/ios/Classes/messages.g.swift diff --git a/packages/ios_platform_images/AUTHORS b/packages/ios_platform_images/AUTHORS index 493a0b4ef9c..0d1bfa6a90c 100644 --- a/packages/ios_platform_images/AUTHORS +++ b/packages/ios_platform_images/AUTHORS @@ -64,3 +64,4 @@ Aleksandr Yurkovskiy Anton Borries Alex Li Rahul Raj <64.rahulraj@gmail.com> +Mairramer diff --git a/packages/ios_platform_images/CHANGELOG.md b/packages/ios_platform_images/CHANGELOG.md index 00259503a20..82b3b09b228 100644 --- a/packages/ios_platform_images/CHANGELOG.md +++ b/packages/ios_platform_images/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.3 + +* Migrates to a Swift implementation. + ## 0.2.2+3 * Converts platform communication to Pigeon. diff --git a/packages/ios_platform_images/README.md b/packages/ios_platform_images/README.md index 9265b108595..69dc63ace5a 100644 --- a/packages/ios_platform_images/README.md +++ b/packages/ios_platform_images/README.md @@ -32,15 +32,15 @@ Widget build(BuildContext context) { } ``` -`IosPlatformImages.load` functions like [[UIImage imageNamed:]](https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed). +`IosPlatformImages.load` works similarly to [`UIImage(named:)`](https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed). ### Flutter->iOS Example -```objc -#import +```swift +import ios_platform_images -static UIImageView* MakeImage() { - UIImage* image = [UIImage flutterImageWithName:@"assets/foo.png"]; - return [[UIImageView alloc] initWithImage:image]; +func makeImage() -> UIImageView { + let image = UIImage.flutterImageWithName("assets/foo.png") + return UIImageView(image: image) } ``` diff --git a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj index ba035186b2f..0813ac0fc15 100644 --- a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,16 +8,17 @@ /* Begin PBXBuildFile section */ 0DE21BF72447752100097E3A /* textfile in Resources */ = {isa = PBXBuildFile; fileRef = 0DE21BF62447752100097E3A /* textfile */; }; + 101538FD877087FE0BE2EA00 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70ED43CFA0E2E576A8AB8B24 /* Pods_Runner.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 33B0E32C2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33B0E32B2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m */; }; + 3131C9A32ADEFDA9000703FA /* UIImage+ios_platform_imagesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3131C9A22ADEFDA8000703FA /* UIImage+ios_platform_imagesTests.m */; }; + 31DC4A212AA8CC9300781E88 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 937254B9D43BF2078EE3DE65 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A144F620445D38CD0FEB7B8E /* Pods_RunnerTests.framework */; }; 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 */; }; - A30D9778BC0D4D09580CF4BE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 906079E3CC5A6FAB808EAF1E /* Pods_Runner.framework */; }; - F76AC1C1266713D00040C8BC /* IosPlatformImagesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.m */; }; - FC73B055B2CD2E32A3E50B27 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD2C5EF0E06B6EC7EBCB922C /* Pods_RunnerTests.framework */; }; + F76AC1C1266713D00040C8BC /* IosPlatformImagesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,14 +50,14 @@ 0EF1CD9A3A3064B5289EF22E /* 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 = ""; }; 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 = ""; }; - 33B0E32B2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ios_platform_imagesTests.m"; sourceTree = ""; }; + 33B0E32B2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ios_platform_imagesTests.m"; sourceTree = ""; }; 3153765C2AAA95AD009694AF /* libios_platform_images.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libios_platform_images.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 4B56C310C5932F84CD6C17AC /* 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 = ""; }; + 70ED43CFA0E2E576A8AB8B24 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 80830F517E3E8B75B2D3AC0A /* 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 = ""; }; - 906079E3CC5A6FAB808EAF1E /* 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; 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; }; @@ -64,11 +65,11 @@ 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 = ""; }; - AD2C5EF0E06B6EC7EBCB922C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A144F620445D38CD0FEB7B8E /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D1A761179BC59B1BAEE63036 /* 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 = ""; }; D36FEDC657E1CE88220062D7 /* 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 = ""; }; F76AC1BE266713D00040C8BC /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IosPlatformImagesTests.m; sourceTree = ""; }; + F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = IosPlatformImagesTests.swift; sourceTree = ""; }; F76AC1C2266713D00040C8BC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -77,7 +78,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A30D9778BC0D4D09580CF4BE /* Pods_Runner.framework in Frameworks */, + 101538FD877087FE0BE2EA00 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -85,7 +86,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FC73B055B2CD2E32A3E50B27 /* Pods_RunnerTests.framework in Frameworks */, + 937254B9D43BF2078EE3DE65 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -156,8 +157,9 @@ DBEBA2309FD49D5C34798105 /* Frameworks */ = { isa = PBXGroup; children = ( - 906079E3CC5A6FAB808EAF1E /* Pods_Runner.framework */, - AD2C5EF0E06B6EC7EBCB922C /* Pods_RunnerTests.framework */, + 3153765C2AAA95AD009694AF /* libios_platform_images.a */, + 70ED43CFA0E2E576A8AB8B24 /* Pods_Runner.framework */, + A144F620445D38CD0FEB7B8E /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -165,9 +167,9 @@ F76AC1BF266713D00040C8BC /* RunnerTests */ = { isa = PBXGroup; children = ( - F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.m */, + 3131C9A22ADEFDA8000703FA /* UIImage+ios_platform_imagesTests.m */, + F76AC1C0266713D00040C8BC /* IosPlatformImagesTests.swift */, F76AC1C2266713D00040C8BC /* Info.plist */, - 33B0E32B2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m */, ); path = RunnerTests; sourceTree = ""; @@ -186,7 +188,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 54C54D6BB826835E8AB0FA51 /* [CP] Embed Pods Frameworks */, + B747922D12365ABBBA69BEA8 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -232,6 +234,7 @@ F76AC1BD266713D00040C8BC = { CreatedOnToolsVersion = 12.5; DevelopmentTeam = S8QB4VV633; + LastSwiftMigration = 1410; ProvisioningStyle = Automatic; TestTargetID = 97C146ED1CF9000F007C117D; }; @@ -273,6 +276,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 31DC4A212AA8CC9300781E88 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -295,26 +299,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 54C54D6BB826835E8AB0FA51 /* [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", - "${BUILT_PRODUCTS_DIR}/ios_platform_images/ios_platform_images.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ios_platform_images.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 73331024E8B67D581A0862F0 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -339,8 +323,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; + buildActionMask = 12; files = ( ); inputPaths = ( @@ -350,7 +333,25 @@ ); 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"; + }; + B747922D12365ABBBA69BEA8 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/ios_platform_images/ios_platform_images.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ios_platform_images.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; C102F13F37851E08F0608EE5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -390,8 +391,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 33B0E32C2AB348FF0006F0C1 /* UIImage+ios_platform_imagesTests.m in Sources */, - F76AC1C1266713D00040C8BC /* IosPlatformImagesTests.m in Sources */, + 3131C9A32ADEFDA9000703FA /* UIImage+ios_platform_imagesTests.m in Sources */, + F76AC1C1266713D00040C8BC /* IosPlatformImagesTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -448,6 +449,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -466,7 +468,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -527,6 +529,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -551,7 +554,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -582,6 +585,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -600,10 +604,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -674,8 +679,14 @@ baseConfigurationReference = 0B20D3254D8E1A2B01D83810 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = S8QB4VV633; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ios_platform_images/ios_platform_images.framework/Headers\"", + $CONFIGURATION_TEMP_DIR/YourProject.build/DerivedSources, + ); INFOPLIST_FILE = RunnerTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -684,6 +695,8 @@ ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; }; name = Debug; @@ -693,8 +706,14 @@ baseConfigurationReference = D36FEDC657E1CE88220062D7 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = S8QB4VV633; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ios_platform_images/ios_platform_images.framework/Headers\"", + $CONFIGURATION_TEMP_DIR/YourProject.build/DerivedSources, + ); INFOPLIST_FILE = RunnerTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -703,6 +722,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; }; name = Release; @@ -712,8 +732,14 @@ baseConfigurationReference = 80830F517E3E8B75B2D3AC0A /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = S8QB4VV633; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ios_platform_images/ios_platform_images.framework/Headers\"", + $CONFIGURATION_TEMP_DIR/YourProject.build/DerivedSources, + ); INFOPLIST_FILE = RunnerTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -722,6 +748,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/Runner"; }; name = Profile; diff --git a/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/packages/ios_platform_images/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/ios_platform_images/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/ios_platform_images/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 51e700a5f8c..42695972f4c 100644 --- a/packages/ios_platform_images/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/ios_platform_images/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -20,6 +20,20 @@ ReferencedContainer = "container:Runner.xcodeproj"> + + + +
- -#import "messages.g.h" - -/// A plugin for Flutter that allows Flutter to load images in a platform -/// specific way on iOS. -@interface IosPlatformImagesPlugin : NSObject -@end diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m deleted file mode 100644 index b41ff9900d8..00000000000 --- a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m +++ /dev/null @@ -1,40 +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 "IosPlatformImagesPlugin.h" - -#if !__has_feature(objc_arc) -#error ARC must be enabled! -#endif - -@interface IosPlatformImagesPlugin () -@end - -@implementation IosPlatformImagesPlugin - -+ (void)registerWithRegistrar:(NSObject *)registrar { - FPIPlatformImagesApiSetup(registrar.messenger, [[IosPlatformImagesPlugin alloc] init]); -} - -- (nullable FPIPlatformImageData *) - loadImageWithName:(nonnull NSString *)name - error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { - UIImage *image = [UIImage imageNamed:name]; - NSData *data = UIImagePNGRepresentation(image); - if (!data) { - return nil; - } - return [FPIPlatformImageData makeWithData:[FlutterStandardTypedData typedDataWithBytes:data] - scale:@(image.scale)]; -} - -- (nullable NSString *)resolveURLForResource:(nonnull NSString *)name - withExtension:(nullable NSString *)extension - error:(FlutterError *_Nullable __autoreleasing *_Nonnull) - error { - NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:extension]; - return url.absoluteString; -} - -@end diff --git a/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.swift b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.swift new file mode 100644 index 00000000000..a47f0673395 --- /dev/null +++ b/packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.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 Flutter +import Foundation + +public final class IosPlatformImagesPlugin: NSObject, FlutterPlugin, PlatformImagesApi { + public static func register(with registrar: FlutterPluginRegistrar) { + let instance = IosPlatformImagesPlugin() + let messenger = registrar.messenger() + PlatformImagesApiSetup.setUp(binaryMessenger: messenger, api: instance) + } + + func loadImage(name: String) -> PlatformImageData? { + guard let image = UIImage(named: name), + let data = image.pngData() + else { + return nil + } + + return PlatformImageData( + data: FlutterStandardTypedData(bytes: data), scale: Double(image.scale)) + } + + func resolveUrl(resourceName: String, extension: String?) throws -> String? { + guard + let url = Bundle.main.url( + forResource: resourceName, + withExtension: `extension`) + else { + return nil + } + + return url.absoluteString + } + +} diff --git a/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.h b/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.h deleted file mode 100644 index 356a5f1cfe3..00000000000 --- a/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.h +++ /dev/null @@ -1,27 +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 - -@interface UIImage (ios_platform_images) - -/// Loads a UIImage from the embedded Flutter project's assets. -/// -/// This method loads the Flutter asset that is appropriate for the current -/// screen. If you are on a 2x retina device where usually `UIImage` would be -/// loading `@2x` assets, it will attempt to load the `2.0x` variant. It will -/// load the standard image if it can't find the `2.0x` variant. -/// -/// For example, if your Flutter project's `pubspec.yaml` lists "assets/foo.png" -/// and "assets/2.0x/foo.png", calling -/// `[UIImage flutterImageWithName:@"assets/foo.png"]` will load -/// "assets/2.0x/foo.png". -/// -/// See also https://flutter.dev/docs/development/ui/assets-and-images -/// -/// Note: We don't yet support images from package dependencies (ex. -/// `AssetImage('icons/heart.png', package: 'my_icons')`). -+ (UIImage *)flutterImageWithName:(NSString *)name; - -@end diff --git a/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.m b/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.m deleted file mode 100644 index f20bbcd08c9..00000000000 --- a/packages/ios_platform_images/ios/Classes/UIImage+ios_platform_images.m +++ /dev/null @@ -1,25 +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 "UIImage+ios_platform_images.h" - -@implementation UIImage (ios_platform_images) -+ (UIImage *)flutterImageWithName:(NSString *)name { - NSString *filename = [name lastPathComponent]; - NSString *path = [name stringByDeletingLastPathComponent]; - for (int screenScale = [UIScreen mainScreen].scale; screenScale > 1; --screenScale) { - NSString *key = [FlutterDartProject - lookupKeyForAsset:[NSString stringWithFormat:@"%@/%d.0x/%@", path, screenScale, filename]]; - UIImage *image = [UIImage imageNamed:key - inBundle:[NSBundle mainBundle] - compatibleWithTraitCollection:nil]; - if (image) { - return image; - } - } - NSString *key = [FlutterDartProject lookupKeyForAsset:name]; - return [UIImage imageNamed:key inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil]; -} -@end diff --git a/packages/ios_platform_images/ios/Classes/UIImageIosPlatformImages.swift b/packages/ios_platform_images/ios/Classes/UIImageIosPlatformImages.swift new file mode 100644 index 00000000000..2e9cdefe673 --- /dev/null +++ b/packages/ios_platform_images/ios/Classes/UIImageIosPlatformImages.swift @@ -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 Flutter +import Foundation +import UIKit + +@objc extension UIImage { + /// Loads a UIImage from the embedded Flutter project's assets. + /// + /// This method loads the Flutter asset that is appropriate for the current + /// screen. If you are on a 2x retina device where usually `UIImage` would be + /// loading `@2x` assets, it will attempt to load the `2.0x` variant. It will + /// load the standard image if it can't find the `2.0x` variant. + /// + /// For example, if your Flutter project's `pubspec.yaml` lists "assets/foo.png" + /// and "assets/2.0x/foo.png", calling + /// `[UIImage flutterImageWithName:@"assets/foo.png"]` will load + /// "assets/2.0x/foo.png". + /// + /// See also https://flutter.dev/docs/development/ui/assets-and-images + /// + /// Note: We don't yet support images from package dependencies (ex. + /// `AssetImage('icons/heart.png', package: 'my_icons')`). + public static func flutterImageWithName(_ name: String) -> UIImage? { + let filename = (name as NSString).lastPathComponent + let path = (name as NSString).deletingLastPathComponent + + for screenScale in stride(from: Int(UIScreen.main.scale), to: 1, by: -1) { + // TODO(hellohuanlin): Fix duplicate slashes in this path construction. + let key = FlutterDartProject.lookupKey(forAsset: "\(path)/\(screenScale).0x/\(filename)") + if let image = UIImage(named: key, in: Bundle.main, compatibleWith: nil) { + return image + } + } + + let key = FlutterDartProject.lookupKey(forAsset: name) + return UIImage(named: key, in: Bundle.main, compatibleWith: nil) + } +} diff --git a/packages/ios_platform_images/ios/Classes/messages.g.h b/packages/ios_platform_images/ios/Classes/messages.g.h deleted file mode 100644 index f4235cf9063..00000000000 --- a/packages/ios_platform_images/ios/Classes/messages.g.h +++ /dev/null @@ -1,47 +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 (v11.0.1), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -#import - -@protocol FlutterBinaryMessenger; -@protocol FlutterMessageCodec; -@class FlutterError; -@class FlutterStandardTypedData; - -NS_ASSUME_NONNULL_BEGIN - -@class FPIPlatformImageData; - -/// A serialization of a platform image's data. -@interface FPIPlatformImageData : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithData:(FlutterStandardTypedData *)data scale:(NSNumber *)scale; -/// The image data. -@property(nonatomic, strong) FlutterStandardTypedData *data; -/// The image's scale factor. -@property(nonatomic, strong) NSNumber *scale; -@end - -/// The codec used by FPIPlatformImagesApi. -NSObject *FPIPlatformImagesApiGetCodec(void); - -@protocol FPIPlatformImagesApi -/// Returns the URL for the given resource, or null if no such resource is -/// found. -- (nullable NSString *)resolveURLForResource:(NSString *)resourceName - withExtension:(nullable NSString *)extension - error:(FlutterError *_Nullable *_Nonnull)error; -/// Returns the data for the image resource with the given name, or null if -/// no such resource is found. -- (nullable FPIPlatformImageData *)loadImageWithName:(NSString *)name - error:(FlutterError *_Nullable *_Nonnull)error; -@end - -extern void FPIPlatformImagesApiSetup(id binaryMessenger, - NSObject *_Nullable api); - -NS_ASSUME_NONNULL_END diff --git a/packages/ios_platform_images/ios/Classes/messages.g.m b/packages/ios_platform_images/ios/Classes/messages.g.m deleted file mode 100644 index b96e65ea263..00000000000 --- a/packages/ios_platform_images/ios/Classes/messages.g.m +++ /dev/null @@ -1,163 +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 (v11.0.1), 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 id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { - id result = array[key]; - return (result == [NSNull null]) ? nil : result; -} - -@interface FPIPlatformImageData () -+ (FPIPlatformImageData *)fromList:(NSArray *)list; -+ (nullable FPIPlatformImageData *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@implementation FPIPlatformImageData -+ (instancetype)makeWithData:(FlutterStandardTypedData *)data scale:(NSNumber *)scale { - FPIPlatformImageData *pigeonResult = [[FPIPlatformImageData alloc] init]; - pigeonResult.data = data; - pigeonResult.scale = scale; - return pigeonResult; -} -+ (FPIPlatformImageData *)fromList:(NSArray *)list { - FPIPlatformImageData *pigeonResult = [[FPIPlatformImageData alloc] init]; - pigeonResult.data = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.data != nil, @""); - pigeonResult.scale = GetNullableObjectAtIndex(list, 1); - NSAssert(pigeonResult.scale != nil, @""); - return pigeonResult; -} -+ (nullable FPIPlatformImageData *)nullableFromList:(NSArray *)list { - return (list) ? [FPIPlatformImageData fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.data ?: [NSNull null]), - (self.scale ?: [NSNull null]), - ]; -} -@end - -@interface FPIPlatformImagesApiCodecReader : FlutterStandardReader -@end -@implementation FPIPlatformImagesApiCodecReader -- (nullable id)readValueOfType:(UInt8)type { - switch (type) { - case 128: - return [FPIPlatformImageData fromList:[self readValue]]; - default: - return [super readValueOfType:type]; - } -} -@end - -@interface FPIPlatformImagesApiCodecWriter : FlutterStandardWriter -@end -@implementation FPIPlatformImagesApiCodecWriter -- (void)writeValue:(id)value { - if ([value isKindOfClass:[FPIPlatformImageData class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else { - [super writeValue:value]; - } -} -@end - -@interface FPIPlatformImagesApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation FPIPlatformImagesApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FPIPlatformImagesApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FPIPlatformImagesApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *FPIPlatformImagesApiGetCodec(void) { - static FlutterStandardMessageCodec *sSharedObject = nil; - static dispatch_once_t sPred = 0; - dispatch_once(&sPred, ^{ - FPIPlatformImagesApiCodecReaderWriter *readerWriter = - [[FPIPlatformImagesApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - -void FPIPlatformImagesApiSetup(id binaryMessenger, - NSObject *api) { - /// Returns the URL for the given resource, or null if no such resource is - /// found. - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.ios_platform_images.PlatformImagesApi.resolveUrl" - binaryMessenger:binaryMessenger - codec:FPIPlatformImagesApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(resolveURLForResource:withExtension:error:)], - @"FPIPlatformImagesApi api (%@) doesn't respond to " - @"@selector(resolveURLForResource:withExtension:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_resourceName = GetNullableObjectAtIndex(args, 0); - NSString *arg_extension = GetNullableObjectAtIndex(args, 1); - FlutterError *error; - NSString *output = [api resolveURLForResource:arg_resourceName - withExtension:arg_extension - error:&error]; - callback(wrapResult(output, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } - /// Returns the data for the image resource with the given name, or null if - /// no such resource is found. - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.ios_platform_images.PlatformImagesApi.loadImage" - binaryMessenger:binaryMessenger - codec:FPIPlatformImagesApiGetCodec()]; - if (api) { - NSCAssert( - [api respondsToSelector:@selector(loadImageWithName:error:)], - @"FPIPlatformImagesApi api (%@) doesn't respond to @selector(loadImageWithName:error:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - NSString *arg_name = GetNullableObjectAtIndex(args, 0); - FlutterError *error; - FPIPlatformImageData *output = [api loadImageWithName:arg_name error:&error]; - callback(wrapResult(output, error)); - }]; - } else { - [channel setMessageHandler:nil]; - } - } -} diff --git a/packages/ios_platform_images/ios/Classes/messages.g.swift b/packages/ios_platform_images/ios/Classes/messages.g.swift new file mode 100644 index 00000000000..30e14c74242 --- /dev/null +++ b/packages/ios_platform_images/ios/Classes/messages.g.swift @@ -0,0 +1,162 @@ +// Copyright 2013 The Flutter 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.1), 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 + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +/// A serialization of a platform image's data. +/// +/// Generated class from Pigeon that represents data sent in messages. +struct PlatformImageData { + /// The image data. + var data: FlutterStandardTypedData + /// The image's scale factor. + var scale: Double + + static func fromList(_ list: [Any?]) -> PlatformImageData? { + let data = list[0] as! FlutterStandardTypedData + let scale = list[1] as! Double + + return PlatformImageData( + data: data, + scale: scale + ) + } + func toList() -> [Any?] { + return [ + data, + scale, + ] + } +} +private class PlatformImagesApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return PlatformImageData.fromList(self.readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class PlatformImagesApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? PlatformImageData { + super.writeByte(128) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class PlatformImagesApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + return PlatformImagesApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + return PlatformImagesApiCodecWriter(data: data) + } +} + +class PlatformImagesApiCodec: FlutterStandardMessageCodec { + static let shared = PlatformImagesApiCodec(readerWriter: PlatformImagesApiCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol PlatformImagesApi { + /// Returns the URL for the given resource, or null if no such resource is + /// found. + func resolveUrl(resourceName: String, extension: String?) throws -> String? + /// Returns the data for the image resource with the given name, or null if + /// no such resource is found. + func loadImage(name: String) throws -> PlatformImageData? +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class PlatformImagesApiSetup { + /// The codec used by PlatformImagesApi. + static var codec: FlutterStandardMessageCodec { PlatformImagesApiCodec.shared } + /// Sets up an instance of `PlatformImagesApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: PlatformImagesApi?) { + /// Returns the URL for the given resource, or null if no such resource is + /// found. + let resolveUrlChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.ios_platform_images.PlatformImagesApi.resolveUrl", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + resolveUrlChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let resourceNameArg = args[0] as! String + let extensionArg: String? = nilOrValue(args[1]) + do { + let result = try api.resolveUrl(resourceName: resourceNameArg, extension: extensionArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + resolveUrlChannel.setMessageHandler(nil) + } + /// Returns the data for the image resource with the given name, or null if + /// no such resource is found. + let loadImageChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.ios_platform_images.PlatformImagesApi.loadImage", + binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + loadImageChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let nameArg = args[0] as! String + do { + let result = try api.loadImage(name: nameArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + loadImageChannel.setMessageHandler(nil) + } + } +} diff --git a/packages/ios_platform_images/ios/ios_platform_images.podspec b/packages/ios_platform_images/ios/ios_platform_images.podspec index 6b67de3f133..d0428215e42 100644 --- a/packages/ios_platform_images/ios/ios_platform_images.podspec +++ b/packages/ios_platform_images/ios/ios_platform_images.podspec @@ -15,11 +15,14 @@ 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/ios_platform_images' } s.documentation_url = 'https://pub.dev/packages/ios_platform_images' - s.source_files = 'Classes/**/*' + s.source_files = 'Classes/**/*.swift' s.dependency 'Flutter' s.platform = :ios, '11.0' - # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. - s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.xcconfig = { + 'DEFINES_MODULE' => 'YES', + 'LIBRARY_SEARCH_PATHS' => '$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)/ $(SDKROOT)/usr/lib/swift', + 'LD_RUNPATH_SEARCH_PATHS' => '/usr/lib/swift', + } s.swift_version = '5.0' end diff --git a/packages/ios_platform_images/lib/ios_platform_images.dart b/packages/ios_platform_images/lib/ios_platform_images.dart index 22e0b84db03..70894f82c8d 100644 --- a/packages/ios_platform_images/lib/ios_platform_images.dart +++ b/packages/ios_platform_images/lib/ios_platform_images.dart @@ -137,7 +137,7 @@ class IosPlatformImages { imageData.then((PlatformImageData? image) { if (image == null) { scaleCompleter.completeError( - Exception("Image couldn't be found: $name"), + Exception("Scale couldn't be found to load image: $name"), ); bytesCompleter.completeError( Exception("Image couldn't be found: $name"), diff --git a/packages/ios_platform_images/pigeons/messages.dart b/packages/ios_platform_images/pigeons/messages.dart index d0a8d347317..36cd9931e5b 100644 --- a/packages/ios_platform_images/pigeons/messages.dart +++ b/packages/ios_platform_images/pigeons/messages.dart @@ -6,9 +6,7 @@ import 'package:pigeon/pigeon.dart'; @ConfigurePigeon(PigeonOptions( dartOut: 'lib/src/messages.g.dart', - objcOptions: ObjcOptions(prefix: 'FPI'), - objcHeaderOut: 'ios/Classes/messages.g.h', - objcSourceOut: 'ios/Classes/messages.g.m', + swiftOut: 'ios/Classes/messages.g.swift', copyrightHeader: 'pigeons/copyright.txt', )) @@ -27,11 +25,9 @@ class PlatformImageData { abstract class PlatformImagesApi { /// Returns the URL for the given resource, or null if no such resource is /// found. - @ObjCSelector('resolveURLForResource:withExtension:') String? resolveUrl(String resourceName, String? extension); /// Returns the data for the image resource with the given name, or null if /// no such resource is found. - @ObjCSelector('loadImageWithName:') PlatformImageData? loadImage(String name); } diff --git a/packages/ios_platform_images/pubspec.yaml b/packages/ios_platform_images/pubspec.yaml index c4a0eee2c69..ac6d7bdb649 100644 --- a/packages/ios_platform_images/pubspec.yaml +++ b/packages/ios_platform_images/pubspec.yaml @@ -2,7 +2,7 @@ name: ios_platform_images description: A plugin to share images between Flutter and iOS in add-to-app setups. repository: https://github.com/flutter/packages/tree/main/packages/ios_platform_images issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+ios_platform_images%22 -version: 0.2.2+3 +version: 0.2.3 environment: sdk: ">=2.19.0 <4.0.0" From 69b166baf2cc74b5520cff4a6f19683ee77e4f3f Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Sat, 21 Oct 2023 12:12:32 -0400 Subject: [PATCH 08/12] Roll Flutter from 0883cb2e962d to 6f4850d74d1a (24 revisions) (#5196) https://github.com/flutter/flutter/compare/0883cb2e962d...6f4850d74d1a 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from a12116df3859 to 11f87dce1017 (1 revision) (flutter/flutter#137017) 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from 755c477c96e7 to a12116df3859 (1 revision) (flutter/flutter#137013) 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from 4f9f4013c3b3 to 755c477c96e7 (1 revision) (flutter/flutter#137008) 2023-10-21 41873024+droidbg@users.noreply.github.com Test cover painting for memory leaks (flutter/flutter#136696) 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from 2e5fb647a76f to 4f9f4013c3b3 (2 revisions) (flutter/flutter#136999) 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from e4fc0c4e2b97 to 2e5fb647a76f (3 revisions) (flutter/flutter#136995) 2023-10-21 engine-flutter-autoroll@skia.org Roll Flutter Engine from 9796817fb6e2 to e4fc0c4e2b97 (1 revision) (flutter/flutter#136993) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 4a65910f0ab2 to 9796817fb6e2 (2 revisions) (flutter/flutter#136990) 2023-10-20 47866232+chunhtai@users.noreply.github.com Adds more a11y use cases (flutter/flutter#136761) 2023-10-20 1961493+harryterkelsen@users.noreply.github.com Reland "Use Layer.toImage for golden tests on CanvasKit" (flutter/flutter#136918) 2023-10-20 49699333+dependabot[bot]@users.noreply.github.com Bump github/codeql-action from 2.22.3 to 2.22.4 (flutter/flutter#136985) 2023-10-20 robert.ancell@canonical.com Add missing call to parent method of GApplication::shutdown, implement GApplication::startup (flutter/flutter#136836) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from b27e1b38375b to 4a65910f0ab2 (5 revisions) (flutter/flutter#136987) 2023-10-20 goderbauer@google.com Bump dartdoc to 7.0.1 and clean-up (flutter/flutter#136975) 2023-10-20 31859944+LongCatIsLooong@users.noreply.github.com RenderEditable WidgetSpan intrinsics (flutter/flutter#136979) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from d46933e6772e to b27e1b38375b (9 revisions) (flutter/flutter#136982) 2023-10-20 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#136924) 2023-10-20 kevinjchisholm@google.com [docs] Expand categories for automated release notes (flutter/flutter#136967) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 21b5c3771ee1 to d46933e6772e (3 revisions) (flutter/flutter#136973) 2023-10-20 jonahwilliams@google.com [Impeller] add OpenGL GPU tracing to devicelab tests. (flutter/flutter#136974) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from f9d1dbc39f4c to 21b5c3771ee1 (1 revision) (flutter/flutter#136969) 2023-10-20 dacoharkes@google.com Default `NativeAssets` Darwin and IOS target archs if missing (flutter/flutter#136948) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 6d1e9eec0841 to f9d1dbc39f4c (1 revision) (flutter/flutter#136966) 2023-10-20 engine-flutter-autoroll@skia.org Roll Flutter Engine from 9b88ff83fd82 to 6d1e9eec0841 (2 revisions) (flutter/flutter#136965) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC rmistry@google.com,stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- .ci/flutter_master.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index 9ce6aa0007d..73cf3e86369 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -0883cb2e962d485c722c1e5628366ba759815454 +6f4850d74d1a25eb4606f0d33c50cae5670fa5db From 826fc0a5f1fcca512899dda85064eeff2b3bfbd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 20:46:24 +0000 Subject: [PATCH 09/12] Bump actions/checkout from 4.1.0 to 4.1.1 (#5167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/release.yml | 2 +- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6bdbc50201f..c2e8c45e1b6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,7 +36,7 @@ jobs: cd $GITHUB_WORKSPACE # Checks out a copy of the repo. - name: Check out code - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 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 index 8aea5583463..8684b69525a 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -21,7 +21,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v2.4.0 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v2.4.0 with: persist-credentials: false From 62ab1eeadfbb8b32aa9887f7a56bd74d3b64071d Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Sun, 22 Oct 2023 12:09:04 -0400 Subject: [PATCH 10/12] Roll Flutter from 6f4850d74d1a to 823e08353dd8 (3 revisions) (#5198) https://github.com/flutter/flutter/compare/6f4850d74d1a...823e08353dd8 2023-10-22 engine-flutter-autoroll@skia.org Roll Flutter Engine from 94f504f2b2a4 to f3c7a50bc83f (1 revision) (flutter/flutter#137031) 2023-10-22 engine-flutter-autoroll@skia.org Roll Flutter Engine from 90995c7f9c1b to 94f504f2b2a4 (1 revision) (flutter/flutter#137028) 2023-10-22 engine-flutter-autoroll@skia.org Roll Flutter Engine from 11f87dce1017 to 90995c7f9c1b (1 revision) (flutter/flutter#137027) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC rmistry@google.com,stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- .ci/flutter_master.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version index 73cf3e86369..a87bee1da80 100644 --- a/.ci/flutter_master.version +++ b/.ci/flutter_master.version @@ -1 +1 @@ -6f4850d74d1a25eb4606f0d33c50cae5670fa5db +823e08353dd820b2f9f8596f8c3ee110a362b45f From a2d8672340ad3192f1a4147c045a98ed71400ecc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 09:04:09 +0000 Subject: [PATCH 11/12] Bump github/codeql-action from 2.22.3 to 2.22.4 (#5201) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.3 to 2.22.4.
Changelog

Sourced from github/codeql-action's changelog.

CodeQL Action Changelog

See the releases page for the relevant changes to the CodeQL CLI and language packs.

[UNRELEASED]

No user facing changes.

2.22.4 - 20 Oct 2023

  • Update default CodeQL bundle version to 2.15.1. #1953
  • Users will begin to see warnings on Node.js 16 deprecation in their Actions logs on code scanning runs starting October 23, 2023.
    • All code scanning workflows should continue to succeed regardless of the warning.
    • The team at GitHub maintaining the CodeQL Action is aware of the deprecation timeline and actively working on creating another version of the CodeQL Action, v3, that will bump us to Node 20.
    • For more information, and to communicate with the maintaining team, please use this issue.

2.22.3 - 13 Oct 2023

  • Provide an authentication token when downloading the CodeQL Bundle from the API of a GitHub Enterprise Server instance. #1945

2.22.2 - 12 Oct 2023

  • Update default CodeQL bundle version to 2.15.0. #1938
  • Improve the log output when an error occurs in an invocation of the CodeQL CLI. #1927

2.22.1 - 09 Oct 2023

  • Add a workaround for Python 3.12, which is not supported in CodeQL CLI version 2.14.6 or earlier. If you are running an analysis on Windows and using Python 3.12 or later, the CodeQL Action will switch to running Python 3.11. In this case, if Python 3.11 is not found, then the workflow will fail. #1928

2.22.0 - 06 Oct 2023

  • The CodeQL Action now requires CodeQL version 2.10.5 or later. For more information, see the corresponding changelog entry for CodeQL Action version 2.21.8. #1907
  • The CodeQL Action no longer runs ML-powered queries. For more information, including details on our investment in AI-powered security technology, see "CodeQL code scanning deprecates ML-powered alerts." #1910
  • Fix a bug which prevented tracing of projects using Go 1.21 and above on Linux. #1909

2.21.9 - 27 Sep 2023

  • Update default CodeQL bundle version to 2.14.6. #1897
  • We are rolling out a feature in October 2023 that will improve the success rate of C/C++ autobuild. #1889
  • We are rolling out a feature in October 2023 that will provide specific file coverage information for C and C++, Java and Kotlin, and JavaScript and TypeScript. Currently file coverage information for each of these pairs of languages is grouped together. #1903
  • Add a warning to help customers avoid inadvertently analyzing the same CodeQL language in multiple matrix jobs. #1901

2.21.8 - 19 Sep 2023

  • Add a deprecation warning for customers using CodeQL version 2.10.4 and earlier. These versions of CodeQL were discontinued on 12 September 2023 alongside GitHub Enterprise Server 3.6, and will be unsupported by the next minor release of the CodeQL Action. #1884
    • If you are using one of these versions, please update to CodeQL CLI version 2.10.5 or later. For instance, if you have specified a custom version of the CLI using the 'tools' input to the 'init' Action, you can remove this input to use the default version.
    • Alternatively, if you want to continue using a version of the CodeQL CLI between 2.9.5 and 2.10.4, you can replace github/codeql-action/*@v2 by github/codeql-action/*@v2.21.7 in your code scanning workflow to ensure you continue using this version of the CodeQL Action.
  • Enable the following language aliases when using CodeQL 2.14.4 and later: c-cpp for C/C++ analysis, java-kotlin for Java/Kotlin analysis, and javascript-typescript for JavaScript/TypeScript analysis. #1883

2.21.7 - 14 Sep 2023

... (truncated)

Commits
  • 49abf0b Merge pull request #1961 from github/update-v2.22.4-63470275e
  • 907abca Update changelog for v2.22.4
  • 6347027 Merge pull request #1953 from github/update-bundle/codeql-bundle-v2.15.1
  • b98a636 Merge branch 'main' into update-bundle/codeql-bundle-v2.15.1
  • 4a368f6 Add announcement on Node 16 deprecation (#1960)
  • 77bbb99 Bump urllib3 in /python-setup/tests/poetry/python-3.8 (#1957)
  • a75a0d5 Bump urllib3 in /python-setup/tests/poetry/requests-3 (#1956)
  • aa55b87 Bump urllib3 in /python-setup/tests/pipenv/requests-3 (#1955)
  • b6b0833 Bump urllib3 in /python-setup/tests/pipenv/python-3.8 (#1954)
  • 0132448 Add changelog note
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=2.22.3&new-version=2.22.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 8684b69525a..e566748fc7f 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -49,6 +49,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v1.0.26 + uses: github/codeql-action/upload-sarif@49abf0ba24d0b7953cb586944e918a0b92074c80 # v1.0.26 with: sarif_file: results.sarif From 4bf51144c295be03f37287600ce7eee438c5b102 Mon Sep 17 00:00:00 2001 From: "Vladimir E. Koltunov" Date: Mon, 23 Oct 2023 15:16:36 +0300 Subject: [PATCH 12/12] [camera] CameraPlatform.createCameraWithSettings (#3615) ## Platform interface of federated plugin This is the `platform-interface` part of `camera` PR #3586. ## App-facing change Previously, CameraController was unable to setup fps and bitrates, allowing only resolution settings like this: ```dart controller = CameraController(_cameras[0], ResolutionPreset.max); ``` This PR gives additional functionality to set `fps` and `bitrates` via `withSettings`: ```dart controller = CameraController.withSettings( _cameras[0], mediaSettings: const MediaSettings( resolutionPreset: ResolutionPreset.low, fps: 15, videoBitrate: 200000, audioBitrate: 32000, enableAudio: true, ), ); ``` ## Android, iOS, etc. All platforms must implement `CameraPlatform.createCameraWithSettings` in addition to `CameraPlatform.createCamera`, providing platform specific code for `fps` and `bitrate' platform: ```dart Future createCamera( CameraDescription cameraDescription, CameraDescription cameraDescription, ResolutionPreset? resolutionPreset, { ResolutionPreset? resolutionPreset, { bool enableAudio = false, bool enableAudio = false, }) { }) => throw UnimplementedError('createCamera() is not implemented.'); createCameraWithSettings( cameraDescription, MediaSettings( resolutionPreset: resolutionPreset, enableAudio: enableAudio, ), ); /// Creates an uninitialized camera instance and returns the cameraId. Future createCameraWithSettings( CameraDescription cameraDescription, MediaSettings? mediaSettings, ) { throw UnimplementedError('createCameraWithSettings() is not implemented.'); } } ``` --- .../camera_platform_interface/CHANGELOG.md | 4 + .../lib/camera_platform_interface.dart | 1 + .../method_channel/method_channel_camera.dart | 20 +- .../platform_interface/camera_platform.dart | 14 ++ .../lib/src/types/media_settings.dart | 77 ++++++ .../lib/src/types/types.dart | 1 + .../camera_platform_interface/pubspec.yaml | 2 +- .../test/camera_platform_interface_test.dart | 75 +++++- .../method_channel_camera_test.dart | 74 ++++-- .../test/types/media_settings_test.dart | 223 ++++++++++++++++++ 10 files changed, 471 insertions(+), 20 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/media_settings.dart create mode 100644 packages/camera/camera_platform_interface/test/types/media_settings_test.dart diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index 62a4140aa52..eaac4bc7ecc 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.6.0 + +* Adds support to control video fps and bitrate. See `CameraPlatform.createCameraWithSettings`. + ## 2.5.2 * Adds pub topics to package metadata. diff --git a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart index 6fab99b3d69..25fc417a9cc 100644 --- a/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart +++ b/packages/camera/camera_platform_interface/lib/camera_platform_interface.dart @@ -8,4 +8,5 @@ export 'package:cross_file/cross_file.dart'; export 'src/events/camera_event.dart'; export 'src/events/device_event.dart'; export 'src/platform_interface/camera_platform.dart'; +export 'src/types/media_settings.dart'; export 'src/types/types.dart'; diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 14d20fc817b..35ece04fdf5 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -88,15 +88,29 @@ class MethodChannelCamera extends CameraPlatform { CameraDescription cameraDescription, ResolutionPreset? resolutionPreset, { bool enableAudio = false, - }) async { + }) async => + createCameraWithSettings( + cameraDescription, + MediaSettings( + resolutionPreset: resolutionPreset, enableAudio: enableAudio)); + + @override + Future createCameraWithSettings( + CameraDescription cameraDescription, + MediaSettings mediaSettings, + ) async { try { + final ResolutionPreset? resolutionPreset = mediaSettings.resolutionPreset; final Map? reply = await _channel .invokeMapMethod('create', { 'cameraName': cameraDescription.name, 'resolutionPreset': resolutionPreset != null - ? _serializeResolutionPreset(resolutionPreset) + ? _serializeResolutionPreset(mediaSettings.resolutionPreset!) : null, - 'enableAudio': enableAudio, + 'fps': mediaSettings.fps, + 'videoBitrate': mediaSettings.videoBitrate, + 'audioBitrate': mediaSettings.audioBitrate, + 'enableAudio': mediaSettings.enableAudio, }); return reply!['cameraId']! as int; 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 b43629d4e0c..b74cb420332 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 @@ -55,6 +55,20 @@ abstract class CameraPlatform extends PlatformInterface { throw UnimplementedError('createCamera() is not implemented.'); } + /// Creates an uninitialized camera instance and returns the cameraId. + /// + /// Pass MediaSettings() for defaults + Future createCameraWithSettings( + CameraDescription cameraDescription, + MediaSettings mediaSettings, + ) { + return createCamera( + cameraDescription, + mediaSettings.resolutionPreset, + enableAudio: mediaSettings.enableAudio, + ); + } + /// Initializes the camera on the device. /// /// [imageFormatGroup] is used to specify the image formatting used. diff --git a/packages/camera/camera_platform_interface/lib/src/types/media_settings.dart b/packages/camera/camera_platform_interface/lib/src/types/media_settings.dart new file mode 100644 index 00000000000..95e29fad7d7 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/media_settings.dart @@ -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. + +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + +import 'resolution_preset.dart'; + +/// Recording media settings. +/// +/// Used in [CameraPlatform.createCameraWithSettings]. +/// Allows to tune recorded video parameters, such as resolution, frame rate, bitrate. +/// If [fps], [videoBitrate] or [audioBitrate] are passed, they must be greater than zero. +class MediaSettings { + /// Creates a [MediaSettings]. + const MediaSettings({ + this.resolutionPreset, + this.fps, + this.videoBitrate, + this.audioBitrate, + this.enableAudio = false, + }) : assert(fps == null || fps > 0, 'fps must be null or greater than zero'), + assert(videoBitrate == null || videoBitrate > 0, + 'videoBitrate must be null or greater than zero'), + assert(audioBitrate == null || audioBitrate > 0, + 'audioBitrate must be null or greater than zero'); + + /// [ResolutionPreset] affect the quality of video recording and image capture. + final ResolutionPreset? resolutionPreset; + + /// Rate at which frames should be captured by the camera in frames per second. + final int? fps; + + /// The video encoding bit rate for recording. + final int? videoBitrate; + + /// The audio encoding bit rate for recording. + final int? audioBitrate; + + /// Controls audio presence in recorded video. + final bool enableAudio; + + @override + bool operator ==(Object other) { + if (identical(other, this)) { + return true; + } + if (other.runtimeType != runtimeType) { + return false; + } + return other is MediaSettings && + resolutionPreset == other.resolutionPreset && + fps == other.fps && + videoBitrate == other.videoBitrate && + audioBitrate == other.audioBitrate && + enableAudio == other.enableAudio; + } + + @override + int get hashCode => Object.hash( + resolutionPreset, + fps, + videoBitrate, + audioBitrate, + enableAudio, + ); + + @override + String toString() { + return 'MediaSettings{' + 'resolutionPreset: $resolutionPreset, ' + 'fps: $fps, ' + 'videoBitrate: $videoBitrate, ' + 'audioBitrate: $audioBitrate, ' + 'enableAudio: $enableAudio}'; + } +} diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index a8a4f8ca5dc..f9a81559d68 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -9,5 +9,6 @@ export 'exposure_mode.dart'; export 'flash_mode.dart'; export 'focus_mode.dart'; export 'image_format_group.dart'; +export 'media_settings.dart'; export 'resolution_preset.dart'; export 'video_capture_options.dart'; diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 09caeda73eb..b0c3a1d8bff 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ 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.5.2 +version: 2.6.0 environment: sdk: ">=2.19.0 <4.0.0" diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart index e3b6858e6d2..6a8ebf65404 100644 --- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart +++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart @@ -163,12 +163,67 @@ void main() { lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + ResolutionPreset.low, ), throwsUnimplementedError, ); }); + test( + 'Default implementation of createCameraWithSettings() should call createCamera() passing parameters', + () { + // Arrange + const CameraDescription cameraDescription = CameraDescription( + name: 'back', + lensDirection: CameraLensDirection.back, + sensorOrientation: 0, + ); + + const MediaSettings mediaSettings = MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ); + + bool createCameraCalled = false; + + final OverriddenCameraPlatform cameraPlatform = OverriddenCameraPlatform(( + CameraDescription cameraDescriptionArg, + ResolutionPreset? resolutionPresetArg, + bool enableAudioArg, + ) { + expect( + cameraDescriptionArg, + cameraDescription, + reason: 'should pass camera description', + ); + expect( + resolutionPresetArg, + mediaSettings.resolutionPreset, + reason: 'should pass resolution preset', + ); + expect( + enableAudioArg, + mediaSettings.enableAudio, + reason: 'should pass enableAudio', + ); + + createCameraCalled = true; + }); + + // Act & Assert + cameraPlatform.createCameraWithSettings( + cameraDescription, + mediaSettings, + ); + + expect(createCameraCalled, isTrue, + reason: + 'default implementation of createCameraWithSettings should call createCamera passing parameters'); + }); + test( 'Default implementation of initializeCamera() should throw unimplemented error', () { @@ -496,3 +551,21 @@ class ImplementsCameraPlatform implements CameraPlatform { } class ExtendsCameraPlatform extends CameraPlatform {} + +class OverriddenCameraPlatform extends CameraPlatform { + OverriddenCameraPlatform(this._onCreateCameraCalled); + + final void Function( + CameraDescription cameraDescription, + ResolutionPreset? resolutionPreset, + bool enableAudio, + ) _onCreateCameraCalled; + + @override + Future createCamera( + CameraDescription cameraDescription, ResolutionPreset? resolutionPreset, + {bool enableAudio = false}) { + _onCreateCameraCalled(cameraDescription, resolutionPreset, enableAudio); + return Future.value(0); + } +} 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 1fd6445e746..8159cdfe26f 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 @@ -33,12 +33,17 @@ void main() { final MethodChannelCamera camera = MethodChannelCamera(); // Act - final int cameraId = await camera.createCamera( + final int cameraId = await camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + ), ); // Assert @@ -47,7 +52,10 @@ void main() { 'create', arguments: { 'cameraName': 'Test', - 'resolutionPreset': 'high', + 'resolutionPreset': 'low', + 'fps': 15, + 'videoBitrate': 200000, + 'audioBitrate': 32000, 'enableAudio': false }, ), @@ -71,13 +79,19 @@ void main() { // Act expect( - () => camera.createCamera( + () => camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ), throwsA( isA() @@ -105,13 +119,19 @@ void main() { // Act expect( - () => camera.createCamera( + () => camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ), throwsA( isA() @@ -167,13 +187,19 @@ void main() { 'initialize': null }); final MethodChannelCamera camera = MethodChannelCamera(); - final int cameraId = await camera.createCamera( + final int cameraId = await camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ); // Act @@ -214,13 +240,19 @@ void main() { }); final MethodChannelCamera camera = MethodChannelCamera(); - final int cameraId = await camera.createCamera( + final int cameraId = await camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ); final Future initializeFuture = camera.initializeCamera(cameraId); camera.cameraEventStreamController.add(CameraInitializedEvent( @@ -262,13 +294,19 @@ void main() { }, ); camera = MethodChannelCamera(); - cameraId = await camera.createCamera( + cameraId = await camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ); final Future initializeFuture = camera.initializeCamera(cameraId); camera.cameraEventStreamController.add(CameraInitializedEvent( @@ -432,13 +470,19 @@ void main() { }, ); camera = MethodChannelCamera(); - cameraId = await camera.createCamera( + cameraId = await camera.createCameraWithSettings( const CameraDescription( name: 'Test', lensDirection: CameraLensDirection.back, sensorOrientation: 0, ), - ResolutionPreset.high, + const MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 15, + videoBitrate: 200000, + audioBitrate: 32000, + enableAudio: true, + ), ); final Future initializeFuture = camera.initializeCamera(cameraId); camera.cameraEventStreamController.add( diff --git a/packages/camera/camera_platform_interface/test/types/media_settings_test.dart b/packages/camera/camera_platform_interface/test/types/media_settings_test.dart new file mode 100644 index 00000000000..242a153107b --- /dev/null +++ b/packages/camera/camera_platform_interface/test/types/media_settings_test.dart @@ -0,0 +1,223 @@ +// Copyright 2013 The Flutter 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: always_specify_types + +import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test( + 'MediaSettings non-parametrized constructor should have correct initial values', + () { + const MediaSettings settingsWithNoParameters = MediaSettings(); + + expect( + settingsWithNoParameters.resolutionPreset, + isNull, + reason: + 'MediaSettings constructor should have null default resolutionPreset', + ); + + expect( + settingsWithNoParameters.fps, + isNull, + reason: 'MediaSettings constructor should have null default fps', + ); + + expect( + settingsWithNoParameters.videoBitrate, + isNull, + reason: 'MediaSettings constructor should have null default videoBitrate', + ); + + expect( + settingsWithNoParameters.audioBitrate, + isNull, + reason: 'MediaSettings constructor should have null default audioBitrate', + ); + + expect( + settingsWithNoParameters.enableAudio, + isFalse, + reason: 'MediaSettings constructor should have false default enableAudio', + ); + }); + + test('MediaSettings fps should hold parameters', () { + const MediaSettings settings = MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 20, + videoBitrate: 128000, + audioBitrate: 32000, + enableAudio: true, + ); + + expect( + settings.resolutionPreset, + ResolutionPreset.low, + reason: + 'MediaSettings constructor should hold resolutionPreset parameter', + ); + + expect( + settings.fps, + 20, + reason: 'MediaSettings constructor should hold fps parameter', + ); + + expect( + settings.videoBitrate, + 128000, + reason: 'MediaSettings constructor should hold videoBitrate parameter', + ); + + expect( + settings.audioBitrate, + 32000, + reason: 'MediaSettings constructor should hold audioBitrate parameter', + ); + + expect( + settings.enableAudio, + true, + reason: 'MediaSettings constructor should hold enableAudio parameter', + ); + }); + + test('MediaSettings hash should be Object.hash of passed parameters', () { + const MediaSettings settings = MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 20, + videoBitrate: 128000, + audioBitrate: 32000, + enableAudio: true, + ); + + expect( + settings.hashCode, + Object.hash(ResolutionPreset.low, 20, 128000, 32000, true), + reason: + 'MediaSettings hash() should be equal to Object.hash of parameters', + ); + }); + + group('MediaSettings == operator', () { + const ResolutionPreset preset1 = ResolutionPreset.low; + const int fps1 = 20; + const int videoBitrate1 = 128000; + const int audioBitrate1 = 32000; + const bool enableAudio1 = true; + + const ResolutionPreset preset2 = ResolutionPreset.high; + const int fps2 = fps1 + 10; + const int videoBitrate2 = videoBitrate1 * 2; + const int audioBitrate2 = audioBitrate1 * 2; + const bool enableAudio2 = !enableAudio1; + + const MediaSettings settings1 = MediaSettings( + resolutionPreset: ResolutionPreset.low, + fps: 20, + videoBitrate: 128000, + audioBitrate: 32000, + enableAudio: true, + ); + + test('should compare resolutionPreset', () { + const MediaSettings settings2 = MediaSettings( + resolutionPreset: preset2, + fps: fps1, + videoBitrate: videoBitrate1, + audioBitrate: audioBitrate1, + enableAudio: enableAudio1, + ); + + expect(settings1 == settings2, isFalse); + }); + + test('should compare fps', () { + const MediaSettings settings2 = MediaSettings( + resolutionPreset: preset1, + fps: fps2, + videoBitrate: videoBitrate1, + audioBitrate: audioBitrate1, + enableAudio: enableAudio1, + ); + + expect(settings1 == settings2, isFalse); + }); + + test('should compare videoBitrate', () { + const MediaSettings settings2 = MediaSettings( + resolutionPreset: preset1, + fps: fps1, + videoBitrate: videoBitrate2, + audioBitrate: audioBitrate1, + enableAudio: enableAudio1, + ); + + expect(settings1 == settings2, isFalse); + }); + + test('should compare audioBitrate', () { + const MediaSettings settings2 = MediaSettings( + resolutionPreset: preset1, + fps: fps1, + videoBitrate: videoBitrate1, + audioBitrate: audioBitrate2, + enableAudio: enableAudio1, + ); + + expect(settings1 == settings2, isFalse); + }); + + test('should compare enableAudio', () { + const MediaSettings settings2 = MediaSettings( + resolutionPreset: preset1, + fps: fps1, + videoBitrate: videoBitrate1, + audioBitrate: audioBitrate1, + // ignore: avoid_redundant_argument_values + enableAudio: enableAudio2, + ); + + expect(settings1 == settings2, isFalse); + }); + + test('should return true when all parameters are equal', () { + const MediaSettings sameSettings = MediaSettings( + resolutionPreset: preset1, + fps: fps1, + videoBitrate: videoBitrate1, + audioBitrate: audioBitrate1, + enableAudio: enableAudio1, + ); + + expect( + settings1 == sameSettings, + isTrue, + ); + }); + + test('Identical objects should be equal', () { + const MediaSettings settingsIdentical = settings1; + + expect( + settings1 == settingsIdentical, + isTrue, + reason: + 'MediaSettings == operator should return true for identical objects', + ); + }); + + test('Objects of different types should be non-equal', () { + expect( + settings1 == Object(), + isFalse, + reason: + 'MediaSettings == operator should return false for objects of different types', + ); + }); + }); +}