diff --git a/.ci.yaml b/.ci.yaml index 0ff2e0aab5..bf712d5663 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -3898,6 +3898,16 @@ targets: ["devicelab", "ios", "mac"] task_name: simple_animation_perf_ios + - name: Mac_ios wide_gamut_ios + recipe: devicelab/devicelab_drone + bringup: true + presubmit: false + timeout: 60 + properties: + tags: > + ["devicelab", "ios", "mac"] + task_name: wide_gamut_ios + - name: Mac_ios simple_animation_perf_impeller_ios recipe: devicelab/devicelab_drone presubmit: false diff --git a/TESTOWNERS b/TESTOWNERS index 47b2a733de..32627ce013 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -87,6 +87,7 @@ /dev/devicelab/bin/tasks/animated_complex_opacity_perf__e2e_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/animated_complex_image_filtered_perf__e2e_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/spell_check_test.dart @camsim99 @flutter/android +/dev/devicelab/bin/tasks/wide_gamut_ios.dart @gaaclarke @flutter/engine ## Windows Android DeviceLab tests /dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @zanderso @flutter/tool diff --git a/dev/devicelab/bin/tasks/wide_gamut_ios.dart b/dev/devicelab/bin/tasks/wide_gamut_ios.dart new file mode 100644 index 0000000000..77b8561d3d --- /dev/null +++ b/dev/devicelab/bin/tasks/wide_gamut_ios.dart @@ -0,0 +1,12 @@ +// Copyright 2014 The Flutter Authors. 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_devicelab/framework/devices.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/integration_tests.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.ios; + await task(createWideGamutTest()); +} diff --git a/dev/devicelab/lib/tasks/integration_tests.dart b/dev/devicelab/lib/tasks/integration_tests.dart index cebf40d248..e9316f1480 100644 --- a/dev/devicelab/lib/tasks/integration_tests.dart +++ b/dev/devicelab/lib/tasks/integration_tests.dart @@ -157,6 +157,14 @@ TaskFunction createWindowsStartupDriverTest({String? deviceIdOverride}) { ).call; } +TaskFunction createWideGamutTest() { + return IntegrationTest( + '${flutterDirectory.path}/dev/integration_tests/wide_gamut_test', + 'integration_test/app_test.dart', + createPlatforms: ['ios'], + ).call; +} + class DriverTest { DriverTest( this.testDirectory, @@ -204,12 +212,14 @@ class IntegrationTest { this.testDirectory, this.testTarget, { this.extraOptions = const [], + this.createPlatforms = const [], } ); final String testDirectory; final String testTarget; final List extraOptions; + final List createPlatforms; Future call() { return inDirectory(testDirectory, () async { @@ -218,6 +228,15 @@ class IntegrationTest { final String deviceId = device.deviceId; await flutter('packages', options: ['get']); + if (createPlatforms.isNotEmpty) { + await flutter('create', options: [ + '--platforms', + createPlatforms.join(','), + '--no-overwrite', + '.' + ]); + } + final List options = [ '-v', '-d', diff --git a/dev/integration_tests/wide_gamut_test/.gitignore b/dev/integration_tests/wide_gamut_test/.gitignore new file mode 100644 index 0000000000..24476c5d1e --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/dev/integration_tests/wide_gamut_test/.metadata b/dev/integration_tests/wide_gamut_test/.metadata new file mode 100644 index 0000000000..68e3f85181 --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: c379133df6d1f8893ad8c9d0393496c7d6eaf828 + channel: wide-gamut-integration-test + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: c379133df6d1f8893ad8c9d0393496c7d6eaf828 + base_revision: c379133df6d1f8893ad8c9d0393496c7d6eaf828 + - platform: ios + create_revision: c379133df6d1f8893ad8c9d0393496c7d6eaf828 + base_revision: c379133df6d1f8893ad8c9d0393496c7d6eaf828 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/dev/integration_tests/wide_gamut_test/README.md b/dev/integration_tests/wide_gamut_test/README.md new file mode 100644 index 0000000000..787ef2c69b --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/README.md @@ -0,0 +1,10 @@ +# wide_gamut_test + +An integration test used for testing wide gamut color support in the engine. + +## Local run + +```sh +flutter create --platforms="ios" --no-overwrite . +flutter test integration_test/app_test.dart +``` diff --git a/dev/integration_tests/wide_gamut_test/integration_test/app_test.dart b/dev/integration_tests/wide_gamut_test/integration_test/app_test.dart new file mode 100644 index 0000000000..92fa5fc432 --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/integration_test/app_test.dart @@ -0,0 +1,62 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:typed_data'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:wide_gamut_test/main.dart' as app; + +// See: https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatbgr10_xr. +double _decodeBGR10(int x) { + const double max = 1.25098; + const double min = -0.752941; + const double intercept = min; + const double slope = (max - min) / 1024.0; + return (x * slope) + intercept; +} + +bool _isAlmost(double x, double y, double epsilon) { + return (x - y).abs() < epsilon; +} + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('end-to-end test', () { + testWidgets('look for display p3 deepest red', (WidgetTester tester) async { + app.main(); + await tester.pumpAndSettle(const Duration(seconds: 2)); + + const MethodChannel channel = MethodChannel('flutter/screenshot'); + final List result = + await channel.invokeMethod('test') as List; + expect(result, isNotNull); + expect(result.length, 4); + final int width = (result[0] as int?)!; + final int height = (result[1] as int?)!; + final String format = (result[2] as String?)!; + expect(format, 'MTLPixelFormatBGR10_XR'); + final Uint8List bytes = (result[3] as Uint8List?)!; + final ByteData byteData = ByteData.sublistView(bytes); + expect(bytes.lengthInBytes, width * height * 4); + expect(bytes.lengthInBytes, byteData.lengthInBytes); + bool foundDeepRed = false; + for (int i = 0; i < bytes.lengthInBytes; i += 4) { + final int pixel = byteData.getUint32(i, Endian.host); + final double blue = _decodeBGR10(pixel & 0x3ff); + final double green = _decodeBGR10((pixel >> 10) & 0x3ff); + final double red = _decodeBGR10((pixel >> 20) & 0x3ff); + if (_isAlmost(red, 1.0931, 0.01) && + _isAlmost(green, -0.2268, 0.01) && + _isAlmost(blue, -0.1501, 0.01)) { + foundDeepRed = true; + } + } + expect(foundDeepRed, isTrue); + }); + }); +} diff --git a/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist b/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist new file mode 100644 index 0000000000..6317e5ef22 --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/ios/Runner/Info.plist @@ -0,0 +1,55 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Wide Gamut Test + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + wide_gamut_test + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + FLTEnableImpeller + + FLTEnableWideGamut + + + diff --git a/dev/integration_tests/wide_gamut_test/lib/main.dart b/dev/integration_tests/wide_gamut_test/lib/main.dart new file mode 100644 index 0000000000..a3ae9c41d0 --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/lib/main.dart @@ -0,0 +1,106 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert' show base64Decode; +import 'package:flutter/material.dart'; + +/// A 100x100 png in Display P3 colorspace. +const String _displayP3Logo = + 'iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAABdWlDQ1BrQ0dDb2xvclNwYWNlRG' + 'lzcGxheVAzAAAokXWQvUvDUBTFT6tS0DqIDh0cMolD1NIKdnFoKxRFMFQFq1OafgltfCQpUnET' + 'Vyn4H1jBWXCwiFRwcXAQRAcR3Zw6KbhoeN6XVNoi3sfl/Ticc7lcwBtQGSv2AijplpFMxKS11L' + 'rke4OHnlOqZrKooiwK/v276/PR9d5PiFlNu3YQ2U9cl84ul3aeAlN//V3Vn8maGv3f1EGNGRbg' + 'kYmVbYsJ3iUeMWgp4qrgvMvHgtMunzuelWSc+JZY0gpqhrhJLKc79HwHl4plrbWD2N6f1VeXxR' + 'zqUcxhEyYYilBRgQQF4X/8044/ji1yV2BQLo8CLMpESRETssTz0KFhEjJxCEHqkLhz634PrfvJ' + 'bW3vFZhtcM4v2tpCAzidoZPV29p4BBgaAG7qTDVUR+qh9uZywPsJMJgChu8os2HmwiF3e38M6H' + 'vh/GMM8B0CdpXzryPO7RqFn4Er/QcXKWq8UwZBywAAAJplWElmTU0AKgAAAAgABQESAAMAAAAB' + 'AAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgExAAIAAAAhAAAAWodpAAQAAAABAAAAfAAAAA' + 'AAAABIAAAAAQAAAEgAAAABQWRvYmUgUGhvdG9zaG9wIDI0LjEgKE1hY2ludG9zaCkAAAACoAIA' + 'BAAAAAEAAABkoAMABAAAAAEAAABkAAAAALGpdjYAAAAJcEhZcwAACxMAAAsTAQCanBgAAAR2aV' + 'RYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1l' + 'dGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaH' + 'R0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6' + 'RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly' + '9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDov' + 'L25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dH' + 'A6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAg' + 'IHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aW' + 'ZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVz' + 'b2x1dGlvbj43MjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb2' + '4+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpw' + 'YXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLm' + 'lpZDpDREE0Mzc3NzhBRjcxMUVEQTU0N0JCNjBEMjUwOTI2RDwvc3RSZWY6aW5zdGFuY2VJRD4K' + 'ICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpDREE0Mzc3ODhBRjcxMUVEQT' + 'U0N0JCNjBEMjUwOTI2RDwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJp' + 'dmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpDREE0Mzc3QThBRj' + 'cxMUVEQTU0N0JCNjBEMjUwOTI2RDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1N' + 'Okluc3RhbmNlSUQ+eG1wLmlpZDpDREE0Mzc3OThBRjcxMUVEQTU0N0JCNjBEMjUwOTI2RDwveG' + '1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3No' + 'b3AgMjQuMSAoTWFjaW50b3NoKTwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcm' + 'lwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KRm6gbQAABNpJREFUeAHtnOty3CAM' + 'hZO2Pzrt+z9qO/3RS/iSOVPGwcTrFZLwoqlDfUPifAgc75Lnf09P5d+yLAp8yhLIiuNNgQUkWU' + '9YQBaQZAokC2dlyAKSTIFk4awMWUCSKZAsnJUhyYB8SRbPkHB4FfG3bM8DaqduerVV3ZcFglCI' + '9KdsP8tm/X6IuoH8uWzfyraAFBH2rIbxo1yk/b3rzxwXjO/lZisYxHG5OUTikxmjYOCDzLCGUa' + 'q8FpDZYVwKSAQMfFrbJYasKBiWc4fATg8kAgbijYBBvVMDiYKBcKNsWiARMPA52qYEEgVj1DBV' + 'Q54OSAQMBPOAgZ+pgETA8BimACGbBkgUDK/MmArIo8AAynNprHdWqjPcVM76buqmRpaLUw9Z6i' + 'meMOTzViGtrk8LBGEYv71heM8ZW5ApgUTAQJhoGMSQDkgUDMTIYKmARMDAZyZLAyQKRoZhqu4Q' + 'KYBEwECEbDCIKRxIFAwan9FCgUTAwGdmCwMSBSPjMFV3kBAgETBodHYYxOgOJAJG9mEKEDJXIF' + 'EwZsgMdyALhiTvly4ZsmD0IdRnhwOJgEEDZxqm3IBEwMDnzDYsQ6JgzJoZ6kRDgCwYkvf20hxI' + 'BAyaPXtmCJ3pkrYIGPKpBrVKrhm5xpDOYNWzTYEQWJbPwAWKeDzWGBY3JmYF9jUYTxg43Bumtj' + 'DIDmujTsRjwaeliGYZ4g2jJ7B3pvZiufWcGVzLcbRuBL396AJLrsUydY63iI7/NANCRaxKRTwJ' + 'czyM9pVbGL16OeedGb142i36+KgZEFwhCGOqBZQWDOpvWQ1DE/jeta37jxzbxsM91j6o0xQIQV' + 'tkyi2Nr2GwLn3E463isfyLDYjfMlMg9BgJdHb4UuO1KJ/9PZMvrznDVKydRpn7uAdKC8besOAN' + 'Q+3a0dHssDkQIlPwlEczZQtD9VBuLQrGXufYxnfP/hAgBHQLlBaMvUZFwFB79mKyPD4MiBohAf' + 'cy5SwMr6cp4vO0oUBoSC9TtjB6jeccdWkCH/k0VT9QeAxT6CRzW9ImQSl5PP1dNt7bqPHlv7um' + 'ewVD+7s3nDhBnUffCJyo/vAtbkCISELSu3+V7WvZPkpR3fMIMIocuRd9RsCQT8SJsI86aERMrz' + '4lDJnhOYF7zxlbgc1ev28rvme/huH5Z/qiYaBZugyJgnFPB7K8Nx0QeimT/sjMoNF6uqMDZLJ0' + 'Q5bn05SyMROQlBkyciwHAhmY1Vx/DzkqAqIxZJEt1nCUFfWrHGsfR9vZui5dhrQEawV+9hjib4' + 'Gzn8XSAZFglHUvthRMPuoszAIlHRCERzDsEaGkBPKG4/+7L89Mke+oMjWQiEwBROTwlRqIeikC' + 'PcrwNQWQiEzBZ0SmTAEkMlPk26ucCkhEpgDCM1OmAqJeeuU5ZUogGt8pPR+JPTJlSiBkShQUZe' + 'moclogUVDwOzJTpgYSBUXZiX9rmx4IgkigK8wplwAiKCpnnugvAwQYmNcjMV9NGvEBWspPDF+V' + 'veOHoFDqM487qnt3a2uIfHfRyQOXBFJrARR6s+WXs2vgwLFcq355IIKDiCMNMBaW7mtAFo1q1W' + 'ElWKtuy2OXm9QtxYmoawGJUL3jcwHpiBNxagGJUL3jcwHpiBNxagGJUL3jcwHpiBNxagGJUL3j' + 'cwHpiBNx6gU/2fLWVmm7wQAAAABJRU5ErkJggg=='; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Wide Gamut Test', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Wide Gamut Test'), + ); + } +} + +class MyHomePage extends StatelessWidget { + const MyHomePage({super.key, required this.title}); + + final String title; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(title), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.memory(base64Decode(_displayP3Logo)), + ], + ), + ), + ); + } +} diff --git a/dev/integration_tests/wide_gamut_test/pubspec.yaml b/dev/integration_tests/wide_gamut_test/pubspec.yaml new file mode 100644 index 0000000000..ad8485839d --- /dev/null +++ b/dev/integration_tests/wide_gamut_test/pubspec.yaml @@ -0,0 +1,44 @@ +name: wide_gamut_test +description: A new Flutter project. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +version: 1.0.0+1 + +environment: + sdk: '>=3.0.0-157.0.dev <4.0.0' + +dependencies: + flutter: + sdk: flutter + + characters: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + collection: 1.17.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + js: 0.6.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + material_color_utilities: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + meta: 1.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + + async: 2.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + fake_async: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + matcher: 0.12.14 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + path: 1.8.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + source_span: 1.9.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stack_trace: 1.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + stream_channel: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + test_api: 0.4.18 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + vm_service: 10.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + +flutter: + uses-material-design: true + +# PUBSPEC CHECKSUM: 79d8