diff --git a/.ci.yaml b/.ci.yaml index 6024a16ff0aaf..a44ca098bb190 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -1940,25 +1940,29 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf - artifact: gallery_app_profile + artifact: gallery__transition_perf - - name: Linux_android flutter_gallery__transition_perf_e2e - recipe: devicelab/devicelab_drone + - name: Linux_build_test flutter_gallery__transition_perf_e2e + recipe: devicelab/devicelab_drone_build_test + bringup: true # New target https://github.com/flutter/flutter/issues/103542 presubmit: false timeout: 60 properties: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf_e2e + artifact: gallery__transition_perf_e2e - - name: Linux_android flutter_gallery__transition_perf_hybrid - recipe: devicelab/devicelab_drone + - name: Linux_build_test flutter_gallery__transition_perf_hybrid + recipe: devicelab/devicelab_drone_build_test + bringup: true # New target https://github.com/flutter/flutter/issues/103542 presubmit: false timeout: 60 properties: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf_hybrid + artifact: gallery__transition_perf_hybrid - name: Linux_android flutter_gallery__transition_perf_with_semantics recipe: devicelab/devicelab_drone @@ -3127,15 +3131,6 @@ targets: ["devicelab", "android", "mac", "arm64"] task_name: run_release_test - - name: Mac_android flutter_gallery_mac__start_up - recipe: devicelab/devicelab_drone - presubmit: false - timeout: 60 - properties: - tags: > - ["devicelab", "android", "mac"] - task_name: flutter_gallery_mac__start_up - - name: Mac_ios animation_with_microtasks_perf_ios__timeline_summary recipe: devicelab/devicelab_drone presubmit: false diff --git a/TESTOWNERS b/TESTOWNERS index dc14a4d9e7f4f..7f2ef06434acc 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -114,7 +114,6 @@ /dev/devicelab/bin/tasks/fading_child_animation_perf__timeline_summary.dart @zanderso @flutter/engine /dev/devicelab/bin/tasks/fast_scroll_large_images__memory.dart @zanderso @flutter/engine /dev/devicelab/bin/tasks/flavors_test.dart @zanderso @flutter/tool -/dev/devicelab/bin/tasks/flutter_gallery_mac__start_up.dart @zanderso @flutter/engine /dev/devicelab/bin/tasks/flutter_view__start_up.dart @zanderso @flutter/engine /dev/devicelab/bin/tasks/fullscreen_textfield_perf__timeline_summary.dart @zanderso @flutter/engine /dev/devicelab/bin/tasks/hello_world_android__compile.dart @zanderso @flutter/tool diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 789e74016159b..22793ceef45dc 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -c0a06da6b228eb8c777f99cbab401d2f644fbc68 +4096e133ef518fc950e74a2ea9b10c1656ddffa0 diff --git a/bin/internal/fuchsia-linux.version b/bin/internal/fuchsia-linux.version index d8a0fc856f427..2703e7465e071 100644 --- a/bin/internal/fuchsia-linux.version +++ b/bin/internal/fuchsia-linux.version @@ -1 +1 @@ -r45MRYVf5_xaCG8bvxdKFwoZtHfF8FtmUzCYGHwuZXQC +nHBOdXRdrHSKPhszb1_gYHMgF_P0j1cmwpfQdJI4gmgC diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version index 81dfded7ab583..5a0559691acfc 100644 --- a/bin/internal/fuchsia-mac.version +++ b/bin/internal/fuchsia-mac.version @@ -1 +1 @@ -JwUV4fO7YBCZli3yNGrmBYr0ofXAbtaqrBZaZR2egCMC +jTGAqMkpVAa0EiLIgeSBEX9byFU6h8-rje_DgDmlSEIC diff --git a/bin/internal/material_fonts.version b/bin/internal/material_fonts.version index 677ef0f74ccdc..237bd69c0beb5 100644 --- a/bin/internal/material_fonts.version +++ b/bin/internal/material_fonts.version @@ -1 +1 @@ -flutter_infra_release/flutter/fonts/d76e4de0ef19d04a55bf3117322be9ced21864aa/fonts.zip +flutter_infra_release/flutter/fonts/3012db47f3130e62f7cc0beabff968a33cbec8d8/fonts.zip diff --git a/dev/bots/analyze_snippet_code.dart b/dev/bots/analyze_snippet_code.dart index 1fce5f60ae707..3a1ed07d8a13b 100644 --- a/dev/bots/analyze_snippet_code.dart +++ b/dev/bots/analyze_snippet_code.dart @@ -980,6 +980,13 @@ class _SnippetChecker { /// Invokes the analyzer on the given [directory] and returns the stdout (with some lines filtered). List _runAnalyzer() { _createConfigurationFiles(); + // Run pub get to avoid output from getting dependencies in the analyzer + // output. + Process.runSync( + _flutter, + ['pub', 'get'], + workingDirectory: _tempDirectory.absolute.path, + ); final ProcessResult result = Process.runSync( _flutter, ['--no-wrap', 'analyze', '--no-preamble', '--no-congratulate', '.'], @@ -1006,7 +1013,7 @@ class _SnippetChecker { if (stdout.isNotEmpty && stdout.first == 'Building flutter tool...') { stdout.removeAt(0); } - if (stdout.isNotEmpty && stdout.first.startsWith('Running "flutter pub get" in ')) { + if (stdout.isNotEmpty && stdout.first.isEmpty) { stdout.removeAt(0); } return stdout; diff --git a/dev/conductor/core/lib/src/state.dart b/dev/conductor/core/lib/src/state.dart index 505440c8ed958..a2d1a77aa06e1 100644 --- a/dev/conductor/core/lib/src/state.dart +++ b/dev/conductor/core/lib/src/state.dart @@ -15,7 +15,7 @@ const String kStateFileName = '.flutter_conductor_state.json'; const String betaPostReleaseMsg = """ 'Ensure the following post release steps are complete:', - '\t 1. Post announcement to discord', + '\t 1. Post announcement to discord and press the publish button', '\t\t Discord: ${globals.discordReleaseChannel}', '\t 2. Post announcement flutter release hotline chat room', '\t\t Chatroom: ${globals.flutterReleaseHotline}', @@ -28,7 +28,7 @@ const String stablePostReleaseMsg = """ '\t\t Best practices: ${globals.hotfixDocumentationBestPractices}', '\t 2. Post announcement to flutter-announce group', '\t\t Flutter Announce: ${globals.flutterAnnounceGroup}', - '\t 3. Post announcement to discord', + '\t 3. Post announcement to discord and press the publish button', '\t\t Discord: ${globals.discordReleaseChannel}', '\t 4. Post announcement flutter release hotline chat room', '\t\t Chatroom: ${globals.flutterReleaseHotline}', diff --git a/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_e2e.dart b/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_e2e.dart index 8a66049914346..24342fa73f0fb 100644 --- a/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_e2e.dart +++ b/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_e2e.dart @@ -6,7 +6,7 @@ import 'package:flutter_devicelab/framework/devices.dart'; import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/tasks/gallery.dart'; -Future main() async { +Future main(List args) async { deviceOperatingSystem = DeviceOperatingSystem.android; - await task(createGalleryTransitionE2ETest()); + await task(createGalleryTransitionE2EBuildTest(args)); } diff --git a/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_hybrid.dart b/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_hybrid.dart index ba6afecdec6cb..5108964ac8640 100644 --- a/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_hybrid.dart +++ b/dev/devicelab/bin/tasks/flutter_gallery__transition_perf_hybrid.dart @@ -6,7 +6,7 @@ import 'package:flutter_devicelab/framework/devices.dart'; import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/tasks/gallery.dart'; -Future main() async { +Future main(List args) async { deviceOperatingSystem = DeviceOperatingSystem.android; - await task(createGalleryTransitionHybridTest()); + await task(createGalleryTransitionHybridBuildTest(args)); } diff --git a/dev/devicelab/bin/tasks/flutter_gallery_mac__start_up.dart b/dev/devicelab/bin/tasks/flutter_gallery_mac__start_up.dart deleted file mode 100644 index c3251993ed22a..0000000000000 --- a/dev/devicelab/bin/tasks/flutter_gallery_mac__start_up.dart +++ /dev/null @@ -1,12 +0,0 @@ -// 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/framework.dart'; -import 'package:flutter_devicelab/tasks/perf_tests.dart'; - -Future main() async { - // It's intended to use the Gallery startup test as a smoke test on macOS - // Catalina. - await task(createFlutterGalleryStartupTest()); -} diff --git a/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart b/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart index 8c4602c86867c..48b0325b1069a 100644 --- a/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart +++ b/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart @@ -15,6 +15,17 @@ Future main() async { final String projectDirectory = '${flutterDirectory.path}/dev/integration_tests/ios_platform_view_tests'; await inDirectory(projectDirectory, () async { + + // To address "Failed to terminate" failure. + section('Uninstall previously installed app'); + + await flutter( + 'install', + options: [ + '--uninstall-only', + ], + ); + section('Build clean'); await flutter('clean'); diff --git a/dev/devicelab/lib/tasks/gallery.dart b/dev/devicelab/lib/tasks/gallery.dart index 4ce08ab82e354..ae03b16d5f546 100644 --- a/dev/devicelab/lib/tasks/gallery.dart +++ b/dev/devicelab/lib/tasks/gallery.dart @@ -25,6 +25,23 @@ TaskFunction createGalleryTransitionTest({bool semanticsEnabled = false}) { return GalleryTransitionTest(semanticsEnabled: semanticsEnabled); } +TaskFunction createGalleryTransitionE2EBuildTest( + List args, { + bool semanticsEnabled = false, + bool enableImpeller = false, +}) { + return GalleryTransitionBuildTest( + args, + testFile: semanticsEnabled ? 'transitions_perf_e2e_with_semantics' : 'transitions_perf_e2e', + needFullTimeline: false, + timelineSummaryFile: 'e2e_perf_summary', + transitionDurationFile: null, + timelineTraceFile: null, + driverFile: 'transitions_perf_e2e_test', + enableImpeller: enableImpeller, + ); +} + TaskFunction createGalleryTransitionE2ETest({ bool semanticsEnabled = false, bool enableImpeller = false, @@ -42,6 +59,17 @@ TaskFunction createGalleryTransitionE2ETest({ ); } +TaskFunction createGalleryTransitionHybridBuildTest( + List args, { + bool semanticsEnabled = false, +}) { + return GalleryTransitionBuildTest( + args, + semanticsEnabled: semanticsEnabled, + driverFile: semanticsEnabled ? 'transitions_perf_hybrid_with_semantics_test' : 'transitions_perf_hybrid_test', + ); +} + TaskFunction createGalleryTransitionHybridTest({bool semanticsEnabled = false}) { return GalleryTransitionTest( semanticsEnabled: semanticsEnabled, @@ -205,12 +233,14 @@ class GalleryTransitionBuildTest extends BuildTestTask { this.driverFile, this.measureCpuGpu = true, this.measureMemory = true, + this.enableImpeller = false, }) : super(workingDirectory: galleryDirectory); final bool semanticsEnabled; final bool needFullTimeline; final bool measureCpuGpu; final bool measureMemory; + final bool enableImpeller; final String testFile; final String timelineSummaryFile; final String? timelineTraceFile; @@ -246,7 +276,9 @@ class GalleryTransitionBuildTest extends BuildTestTask { List getTestArgs(DeviceOperatingSystem deviceOperatingSystem, String deviceId) { final String testDriver = driverFile ?? (semanticsEnabled ? '${testFile}_with_semantics_test' : '${testFile}_test'); return [ + '--no-dds', '--profile', + if (enableImpeller) '--enable-impeller', if (needFullTimeline) '--trace-startup', '-t', 'test_driver/$testFile.dart', diff --git a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart index 0fc6a52e91a70..477b423a92aa6 100644 --- a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart +++ b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart @@ -42,11 +42,10 @@ TaskFunction createWebDevModeTest(String webDevice, bool enableIncrementalCompil recursiveCopy(flutterGalleryDir, _editedFlutterGalleryDir); await inDirectory(_editedFlutterGalleryDir, () async { { - final Process packagesGet = await startProcess( + await exec( path.join(flutterDirectory.path, 'bin', 'flutter'), ['packages', 'get'], ); - await packagesGet.exitCode; final Process process = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), flutterCommandArgs('run', options), diff --git a/dev/integration_tests/ios_platform_view_tests/ios/PlatformViewUITests/PlatformViewUITests.m b/dev/integration_tests/ios_platform_view_tests/ios/PlatformViewUITests/PlatformViewUITests.m index 63ea56625cd25..8663abc234d44 100644 --- a/dev/integration_tests/ios_platform_view_tests/ios/PlatformViewUITests/PlatformViewUITests.m +++ b/dev/integration_tests/ios_platform_view_tests/ios/PlatformViewUITests/PlatformViewUITests.m @@ -26,45 +26,6 @@ - (void)setUp { [super setUp]; self.continueAfterFailure = NO; - // Delete the previously installed app if needed before running. - // This is to address "Failed to terminate" failure. - // The solution is based on https://stackoverflow.com/questions/50016018/uitest-failed-to-terminate-com-test-abc3708-after-60-0s-state-is-still-runnin - XCUIApplication *springboard = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; - [springboard activate]; - XCUIElement *appIcon = springboard.icons[@"ios_platform_view_tests"]; - - if ([appIcon waitForExistenceWithTimeout:kStandardTimeOut]) { - NSLog(@"Deleting previously installed app."); - - // It's possible that app icon is not hittable yet. - NSPredicate *hittable = [NSPredicate predicateWithFormat:@"exists == YES AND hittable == YES"]; - [self expectationForPredicate:hittable evaluatedWithObject:appIcon handler:nil]; - [self waitForExpectationsWithTimeout:kStandardTimeOut handler:nil]; - - // Pressing for 2 seconds will bring up context menu. - // Pressing for 3 seconds will dismiss the context menu and make icons wiggle. - [appIcon pressForDuration:2]; - - // The "Remove App" button in context menu. - XCUIElement *contextMenuRemoveButton = springboard.buttons[@"Remove App"]; - XCTAssert([contextMenuRemoveButton waitForExistenceWithTimeout:kStandardTimeOut], @"The context menu remove app button must appear."); - [contextMenuRemoveButton tap]; - - // Tap the delete confirmation - XCUIElement *deleteConfirmationButton = springboard.alerts.buttons[@"Delete App"]; - XCTAssert([deleteConfirmationButton waitForExistenceWithTimeout:kStandardTimeOut], @"The first delete confirmation button must appear."); - [deleteConfirmationButton tap]; - - // Tap the second delete confirmation - XCUIElement *secondDeleteConfirmationButton = springboard.alerts.buttons[@"Delete"]; - XCTAssert([secondDeleteConfirmationButton waitForExistenceWithTimeout:kStandardTimeOut], @"The second delete confirmation button must appear."); - [secondDeleteConfirmationButton tap]; - - [NSThread sleepForTimeInterval:3]; - } else { - NSLog(@"No previously installed app found."); - } - self.app = [[XCUIApplication alloc] init]; [self.app launch]; } diff --git a/examples/platform_view/lib/main.dart b/examples/platform_view/lib/main.dart index 00b3c48163693..198dcdf2435e0 100644 --- a/examples/platform_view/lib/main.dart +++ b/examples/platform_view/lib/main.dart @@ -54,10 +54,11 @@ class _MyHomePageState extends State { case TargetPlatform.iOS: return const Text('Continue in iOS view'); case TargetPlatform.windows: - return const Text('Cotninue in Windows view'); + return const Text('Continue in Windows view'); + case TargetPlatform.macOS: + return const Text('Continue in macOS view'); case TargetPlatform.fuchsia: case TargetPlatform.linux: - case TargetPlatform.macOS: throw UnimplementedError('Platform not yet implemented'); } } diff --git a/examples/platform_view/macos/.gitignore b/examples/platform_view/macos/.gitignore new file mode 100644 index 0000000000000..746adbb6b9e14 --- /dev/null +++ b/examples/platform_view/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/examples/platform_view/macos/Flutter/Flutter-Debug.xcconfig b/examples/platform_view/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000000000..c2efd0b608ba8 --- /dev/null +++ b/examples/platform_view/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/examples/platform_view/macos/Flutter/Flutter-Release.xcconfig b/examples/platform_view/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000000000..c2efd0b608ba8 --- /dev/null +++ b/examples/platform_view/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/examples/platform_view/macos/Runner.xcodeproj/project.pbxproj b/examples/platform_view/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000..e590827da5806 --- /dev/null +++ b/examples/platform_view/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,581 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + F34FE5C128C663500068B3C3 /* PlatformViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F34FE5BF28C663500068B3C3 /* PlatformViewController.swift */; }; + F34FE5C228C663500068B3C3 /* PlatformViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F34FE5C028C663500068B3C3 /* PlatformViewController.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* platform_view.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = platform_view.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + F34FE5BF28C663500068B3C3 /* PlatformViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewController.swift; sourceTree = ""; }; + F34FE5C028C663500068B3C3 /* PlatformViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PlatformViewController.xib; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* platform_view.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + F34FE5BF28C663500068B3C3 /* PlatformViewController.swift */, + F34FE5C028C663500068B3C3 /* PlatformViewController.xib */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* platform_view.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + F34FE5C228C663500068B3C3 /* PlatformViewController.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + F34FE5C128C663500068B3C3 /* PlatformViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/examples/platform_view/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/platform_view/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/examples/platform_view/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/platform_view/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/platform_view/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000000..28e99e79a14c7 --- /dev/null +++ b/examples/platform_view/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/platform_view/macos/Runner.xcworkspace/contents.xcworkspacedata b/examples/platform_view/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000..1d526a16ed0f1 --- /dev/null +++ b/examples/platform_view/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/platform_view/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/platform_view/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/examples/platform_view/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/platform_view/macos/Runner/AppDelegate.swift b/examples/platform_view/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000000000..d080d41951d35 --- /dev/null +++ b/examples/platform_view/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +// 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 Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/examples/platform_view/macos/Runner/Base.lproj/MainMenu.xib b/examples/platform_view/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000000000..80e867a4e06b4 --- /dev/null +++ b/examples/platform_view/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/platform_view/macos/Runner/Configs/AppInfo.xcconfig b/examples/platform_view/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000000000..0ec4e5a45b55f --- /dev/null +++ b/examples/platform_view/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = platform_view + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = io.flutter.examples.platformView + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 io.flutter.examples. All rights reserved. diff --git a/examples/platform_view/macos/Runner/Configs/Debug.xcconfig b/examples/platform_view/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000000000..36b0fd9464f45 --- /dev/null +++ b/examples/platform_view/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/examples/platform_view/macos/Runner/Configs/Release.xcconfig b/examples/platform_view/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000000000..dff4f49561c81 --- /dev/null +++ b/examples/platform_view/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/examples/platform_view/macos/Runner/Configs/Warnings.xcconfig b/examples/platform_view/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000000000..42bcbf4780b18 --- /dev/null +++ b/examples/platform_view/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/examples/platform_view/macos/Runner/DebugProfile.entitlements b/examples/platform_view/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000000000..dddb8a30c851e --- /dev/null +++ b/examples/platform_view/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/examples/platform_view/macos/Runner/Info.plist b/examples/platform_view/macos/Runner/Info.plist new file mode 100644 index 0000000000000..4789daa6a443e --- /dev/null +++ b/examples/platform_view/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/platform_view/macos/Runner/MainFlutterWindow.swift b/examples/platform_view/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000000000..9686c15bc80ad --- /dev/null +++ b/examples/platform_view/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,38 @@ +// 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 Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + RegisterMethodChannel(registry: flutterViewController) + + super.awakeFromNib() + } + + func RegisterMethodChannel(registry: FlutterPluginRegistry) { + let registrar = registry.registrar(forPlugin: "platform_view") + let channel = FlutterMethodChannel(name: "samples.flutter.io/platform_view", + binaryMessenger: registrar.messenger) + channel.setMethodCallHandler({ (call, result) in + if (call.method == "switchView") { + let count = call.arguments as! Int + let controller: NSViewController = PlatformViewController( + withCount: count, + onClose: { platformViewController in + result(platformViewController.count) + } + ) + self.contentViewController?.presentAsSheet(controller) + } + }) + } +} diff --git a/examples/platform_view/macos/Runner/PlatformViewController.swift b/examples/platform_view/macos/Runner/PlatformViewController.swift new file mode 100644 index 0000000000000..34b242bdc5ffe --- /dev/null +++ b/examples/platform_view/macos/Runner/PlatformViewController.swift @@ -0,0 +1,46 @@ +// 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 Cocoa + +class PlatformViewController: NSViewController { + var count: Int = 0 + + var dispose: ((PlatformViewController)->())? + + @IBOutlet weak var label: NSTextField! + + var labelText: String { + get { + return "Button tapped \(self.count) time\(self.count != 1 ? "s" : "")." + } + } + + override func viewDidLoad() { + super.viewDidLoad() + self.label.stringValue = labelText + } + + public required init?(coder aDecoder: NSCoder) { + self.count = 0 + self.dispose = nil + super.init(coder: aDecoder) + } + + init(withCount count: Int, onClose dispose: ((PlatformViewController)->())?) { + self.count = count + self.dispose = dispose + super.init(nibName: nil, bundle: nil) + } + + @IBAction func pop(_ sender: Any) { + self.dispose?(self) + dismiss(self) + } + + @IBAction func increment(_ sender: Any) { + self.count += 1 + self.label.stringValue = labelText + } +} diff --git a/examples/platform_view/macos/Runner/PlatformViewController.xib b/examples/platform_view/macos/Runner/PlatformViewController.xib new file mode 100644 index 0000000000000..82a80df93e921 --- /dev/null +++ b/examples/platform_view/macos/Runner/PlatformViewController.xib @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/platform_view/macos/Runner/Release.entitlements b/examples/platform_view/macos/Runner/Release.entitlements new file mode 100644 index 0000000000000..852fa1a4728ae --- /dev/null +++ b/examples/platform_view/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/packages/flutter/lib/fix_data.yaml b/packages/flutter/lib/fix_data.yaml index d77969bca88f2..d44f715815a01 100644 --- a/packages/flutter/lib/fix_data.yaml +++ b/packages/flutter/lib/fix_data.yaml @@ -17,6 +17,80 @@ version: 1 transforms: + # Changes made in https://github.com/flutter/flutter/pull/111080 + - title: "Migrate to 'BottomAppBarTheme.color'" + date: 2022-09-07 + element: + uris: [ 'material.dart' ] + constructor: '' + inClass: 'ThemeData' + oneOf: + - if: "bottomAppBarColor != ''" + changes: + - kind: 'removeParameter' + name: 'bottomAppBarColor' + - kind: 'addParameter' + index: 73 + name: 'bottomAppBarTheme' + style: optional_named + argumentValue: + expression: 'BottomAppBarTheme(color: {% bottomAppBarColor %})' + requiredIf: "bottomAppBarColor != ''" + variables: + bottomAppBarColor: + kind: 'fragment' + value: 'arguments[bottomAppBarColor]' + + # Changes made in https://github.com/flutter/flutter/pull/111080 + - title: "Migrate to 'BottomAppBarTheme.color'" + date: 2022-09-07 + element: + uris: [ 'material.dart' ] + constructor: 'raw' + inClass: 'ThemeData' + oneOf: + - if: "bottomAppBarColor != ''" + changes: + - kind: 'removeParameter' + name: 'bottomAppBarColor' + - kind: 'addParameter' + index: 73 + name: 'bottomAppBarTheme' + style: optional_named + argumentValue: + expression: 'BottomAppBarTheme(color: {% bottomAppBarColor %})' + requiredIf: "bottomAppBarColor != ''" + variables: + bottomAppBarColor: + kind: 'fragment' + value: 'arguments[bottomAppBarColor]' + + # Changes made in https://github.com/flutter/flutter/pull/111080 + - title: "Migrate to 'BottomAppBarTheme.color'" + date: 2022-09-06 + element: + uris: [ 'material.dart' ] + method: 'copyWith' + inClass: 'ThemeData' + oneOf: + - if: "bottomAppBarColor != ''" + changes: + - kind: 'removeParameter' + name: 'bottomAppBarColor' + - kind: 'addParameter' + index: 73 + name: 'bottomAppBarTheme' + style: optional_named + argumentValue: + expression: 'BottomAppBarTheme(color: {% bottomAppBarColor %})' + requiredIf: "bottomAppBarColor != ''" + variables: + bottomAppBarColor: + kind: 'fragment' + value: 'arguments[bottomAppBarColor]' + + + # Changes made in https://github.com/flutter/flutter/pull/110162 - title: "Migrate to 'ColorScheme.background'" date: 2022-08-24 diff --git a/packages/flutter/lib/foundation.dart b/packages/flutter/lib/foundation.dart index edb99cc831ba0..3b576adda337e 100644 --- a/packages/flutter/lib/foundation.dart +++ b/packages/flutter/lib/foundation.dart @@ -41,6 +41,7 @@ export 'src/foundation/persistent_hash_map.dart'; export 'src/foundation/platform.dart'; export 'src/foundation/print.dart'; export 'src/foundation/serialization.dart'; +export 'src/foundation/service_extensions.dart'; export 'src/foundation/stack_frame.dart'; export 'src/foundation/synchronous_future.dart'; export 'src/foundation/unicode.dart'; diff --git a/packages/flutter/lib/rendering.dart b/packages/flutter/lib/rendering.dart index b0029c160fca6..a00a220681ccb 100644 --- a/packages/flutter/lib/rendering.dart +++ b/packages/flutter/lib/rendering.dart @@ -55,6 +55,7 @@ export 'src/rendering/proxy_box.dart'; export 'src/rendering/proxy_sliver.dart'; export 'src/rendering/rotated_box.dart'; export 'src/rendering/selection.dart'; +export 'src/rendering/service_extensions.dart'; export 'src/rendering/shifted_box.dart'; export 'src/rendering/sliver.dart'; export 'src/rendering/sliver_fill.dart'; diff --git a/packages/flutter/lib/src/cupertino/date_picker.dart b/packages/flutter/lib/src/cupertino/date_picker.dart index 68ab6d56fb069..19b0a256f72ff 100644 --- a/packages/flutter/lib/src/cupertino/date_picker.dart +++ b/packages/flutter/lib/src/cupertino/date_picker.dart @@ -208,7 +208,7 @@ enum _PickerColumnType { /// /// {@tool dartpad} /// This sample shows how to implement CupertinoDatePicker with different picker modes. -/// We can provide intiial dateTime value for the picker to display. When user changes +/// We can provide initial dateTime value for the picker to display. When user changes /// the drag the date or time wheels, the picker will call onDateTimeChanged callback. /// /// CupertinoDatePicker can be displayed directly on a screen or in a popup. diff --git a/packages/flutter/lib/src/cupertino/dialog.dart b/packages/flutter/lib/src/cupertino/dialog.dart index 1e4e6c05d798a..0cec4f9fd71bb 100644 --- a/packages/flutter/lib/src/cupertino/dialog.dart +++ b/packages/flutter/lib/src/cupertino/dialog.dart @@ -158,7 +158,7 @@ bool _isInAccessibilityMode(BuildContext context) { /// {@youtube 560 315 https://www.youtube.com/watch?v=75CsnyRXf5I} /// /// An alert dialog informs the user about situations that require -/// acknowledgement. An alert dialog has an optional title, optional content, +/// acknowledgment. An alert dialog has an optional title, optional content, /// and an optional list of actions. The title is displayed above the content /// and the actions are displayed below the content. /// @@ -1589,7 +1589,7 @@ class _ActionButtonParentData extends MultiChildLayoutParentData { /// See also: /// /// * [CupertinoAlertDialog], a dialog that informs the user about situations -/// that require acknowledgement. +/// that require acknowledgment. class CupertinoDialogAction extends StatelessWidget { /// Creates an action for an iOS-style dialog. const CupertinoDialogAction({ diff --git a/packages/flutter/lib/src/cupertino/list_section.dart b/packages/flutter/lib/src/cupertino/list_section.dart index c7fdbb297d946..bdcb445c86143 100644 --- a/packages/flutter/lib/src/cupertino/list_section.dart +++ b/packages/flutter/lib/src/cupertino/list_section.dart @@ -216,7 +216,7 @@ class CupertinoListSection extends StatelessWidget { additionalDividerMargin = additionalDividerMargin ?? (hasLeading ? _kBaseAdditionalDividerMargin : 0.0); - /// Creates a section that mimicks standard "Inset Grouped" iOS list section. + /// Creates a section that mimics standard "Inset Grouped" iOS list section. /// /// The [CupertinoListSection.insetGrouped] constructor creates a round-edged /// and padded section that is seen in iOS Notes and Reminders apps. It creates diff --git a/packages/flutter/lib/src/cupertino/list_tile.dart b/packages/flutter/lib/src/cupertino/list_tile.dart index b1ea4d1ec5479..94feeb37d8d5f 100644 --- a/packages/flutter/lib/src/cupertino/list_tile.dart +++ b/packages/flutter/lib/src/cupertino/list_tile.dart @@ -45,7 +45,7 @@ enum _CupertinoListTileType { base, notched } /// take care of text wrapping. /// /// The size of [leading] is by default constrained to match the iOS size, -/// depending of the type of list tile. This can however be overriden by +/// depending of the type of list tile. This can however be overridden by /// providing [leadingSize]. The [trailing] widget is not constrained and is /// therefore a responsibility of the caller to ensure reasonable size of the /// [trailing] widget. @@ -60,7 +60,7 @@ enum _CupertinoListTileType { base, notched } /// /// The [onTap] callback provides an option to react to taps anywhere inside the /// list tile. This can be used to navigate routes and according to iOS -/// behaviour it should not be used for example to toggle the [CupertinoSwitch] +/// behavior it should not be used for example to toggle the [CupertinoSwitch] /// in the trailing widget. /// /// See also: @@ -91,9 +91,9 @@ class CupertinoListTile extends StatefulWidget { /// /// The [onTap] parameter is used to provide an action that is called when the /// tile is tapped. It is mainly used for navigating to a new route. It should - /// not be used to toggle a trailing [CupertinoSwitch] and similar usecases + /// not be used to toggle a trailing [CupertinoSwitch] and similar use cases /// because when tile is tapped, it switches the background color and remains - /// changed. This is according to iOS behaviour. + /// changed. This is according to iOS behavior. /// /// The [backgroundColor] provides a custom background color for the tile in /// a state before tapped. By default, it matches the theme's background color @@ -154,9 +154,9 @@ class CupertinoListTile extends StatefulWidget { /// /// The [onTap] parameter is used to provide an action that is called when the /// tile is tapped. It is mainly used for navigating to a new route. It should - /// not be used to toggle a trailing [CupertinoSwitch] and similar usecases + /// not be used to toggle a trailing [CupertinoSwitch] and similar use cases /// because when tile is tapped, it switches the background color and remains - /// changed. This is according to iOS behaviour. + /// changed. This is according to iOS behavior. /// /// The [backgroundColor] provides a custom background color for the tile in /// a state before tapped. By default, it matches the theme's background color @@ -218,7 +218,7 @@ class CupertinoListTile extends StatefulWidget { /// The [onTap] function is called when a user taps on [CupertinoListTile]. If /// left `null`, the [CupertinoListTile] will not react on taps. If this is a /// `Future Function()`, then the [CupertinoListTile] remains activated - /// until the returned future is awaited. This is according to iOS behaviour. + /// until the returned future is awaited. This is according to iOS behavior. /// However, if this function is a `void Function()`, then the tile is active /// only for the duration of invocation. final FutureOr Function()? onTap; diff --git a/packages/flutter/lib/src/cupertino/magnifier.dart b/packages/flutter/lib/src/cupertino/magnifier.dart index 128a7ce944740..24f636b4faffa 100644 --- a/packages/flutter/lib/src/cupertino/magnifier.dart +++ b/packages/flutter/lib/src/cupertino/magnifier.dart @@ -266,7 +266,7 @@ class CupertinoMagnifier extends StatelessWidget { /// The default size of the magnifier. /// /// This is public so that positioners can choose to depend on it, although - /// it is overrideable. + /// it is overridable. @visibleForTesting static const Size kDefaultSize = Size(80, 47.5); diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart index 3b7bf0c8baa0c..5718c35174d4e 100644 --- a/packages/flutter/lib/src/cupertino/text_field.dart +++ b/packages/flutter/lib/src/cupertino/text_field.dart @@ -182,7 +182,7 @@ class CupertinoTextField extends StatefulWidget { /// the number of lines. In this mode, the intrinsic height of the widget will /// grow as the number of lines of text grows. By default, it is `1`, meaning /// this is a single-line text field and will scroll horizontally when - /// overflown. [maxLines] must not be zero. + /// it overflows. [maxLines] must not be zero. /// /// The text cursor is not shown if [showCursor] is false or if [showCursor] /// is null (the default) and [readOnly] is true. @@ -351,7 +351,7 @@ class CupertinoTextField extends StatefulWidget { /// the number of lines. In this mode, the intrinsic height of the widget will /// grow as the number of lines of text grows. By default, it is `1`, meaning /// this is a single-line text field and will scroll horizontally when - /// overflown. [maxLines] must not be zero. + /// it overflows. [maxLines] must not be zero. /// /// The text cursor is not shown if [showCursor] is false or if [showCursor] /// is null (the default) and [readOnly] is true. @@ -794,7 +794,7 @@ class CupertinoTextField extends StatefulWidget { /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details} /// /// By default, builds a [CupertinoTextMagnifier] on iOS and Android nothing on all other - /// platforms. If it is desired to supress the magnifier, consider passing + /// platforms. If it is desired to suppress the magnifier, consider passing /// [TextMagnifierConfiguration.disabled]. /// // TODO(antholeole): https://github.com/flutter/flutter/issues/108041 diff --git a/packages/flutter/lib/src/foundation/assertions.dart b/packages/flutter/lib/src/foundation/assertions.dart index 3143a022bdf00..c43d958de3173 100644 --- a/packages/flutter/lib/src/foundation/assertions.dart +++ b/packages/flutter/lib/src/foundation/assertions.dart @@ -1042,7 +1042,7 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti /// Adds a stack filtering function to [defaultStackFilter]. /// /// For example, the framework adds common patterns of element building to - /// elide tree-walking patterns in the stacktrace. + /// elide tree-walking patterns in the stack trace. /// /// Added filters are checked in order of addition. The first matching filter /// wins, and subsequent filters will not be checked. @@ -1232,7 +1232,7 @@ void debugPrintStack({StackTrace? stackTrace, String? label, int? maxFrames}) { class DiagnosticsStackTrace extends DiagnosticsBlock { /// Creates a diagnostic for a stack trace. /// - /// [name] describes a name the stacktrace is given, e.g. + /// [name] describes a name the stack trace is given, e.g. /// `When the exception was thrown, this was the stack`. /// [stackFilter] provides an optional filter to use to filter which frames /// are included. If no filter is specified, [FlutterError.defaultStackFilter] diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart index 5acfa98f0124c..ba23cb3d42321 100644 --- a/packages/flutter/lib/src/foundation/binding.dart +++ b/packages/flutter/lib/src/foundation/binding.dart @@ -18,6 +18,7 @@ import 'debug.dart'; import 'object.dart'; import 'platform.dart'; import 'print.dart'; +import 'service_extensions.dart'; export 'dart:ui' show PlatformDispatcher, SingletonFlutterWindow; @@ -109,7 +110,7 @@ typedef ServiceExtensionCallback = Future> Function(Map connectedVmServiceUri ?? '', setter: (String uri) async { connectedVmServiceUri = uri; }, ); registerStringServiceExtension( - name: 'activeDevToolsServerAddress', + name: FoundationServiceExtensions.activeDevToolsServerAddress.name, getter: () async => activeDevToolsServerAddress ?? '', setter: (String serverAddress) async { activeDevToolsServerAddress = serverAddress; @@ -455,9 +456,8 @@ abstract class BindingBase { } assert(() { - const String platformOverrideExtensionName = 'platformOverride'; registerServiceExtension( - name: platformOverrideExtensionName, + name: FoundationServiceExtensions.platformOverride.name, callback: (Map parameters) async { if (parameters.containsKey('value')) { switch (parameters['value']) { @@ -484,7 +484,7 @@ abstract class BindingBase { debugDefaultTargetPlatformOverride = null; } _postExtensionStateChangedEvent( - platformOverrideExtensionName, + FoundationServiceExtensions.platformOverride.name, defaultTargetPlatform.toString().substring('$TargetPlatform.'.length), ); await reassembleApplication(); @@ -497,9 +497,8 @@ abstract class BindingBase { }, ); - const String brightnessOverrideExtensionName = 'brightnessOverride'; registerServiceExtension( - name: brightnessOverrideExtensionName, + name: FoundationServiceExtensions.brightnessOverride.name, callback: (Map parameters) async { if (parameters.containsKey('value')) { switch (parameters['value']) { @@ -513,7 +512,7 @@ abstract class BindingBase { debugBrightnessOverride = null; } _postExtensionStateChangedEvent( - brightnessOverrideExtensionName, + FoundationServiceExtensions.brightnessOverride.name, (debugBrightnessOverride ?? platformDispatcher.platformBrightness).toString(), ); await reassembleApplication(); diff --git a/packages/flutter/lib/src/foundation/persistent_hash_map.dart b/packages/flutter/lib/src/foundation/persistent_hash_map.dart index 0904c3b870b8e..411dca02b2b60 100644 --- a/packages/flutter/lib/src/foundation/persistent_hash_map.dart +++ b/packages/flutter/lib/src/foundation/persistent_hash_map.dart @@ -390,7 +390,7 @@ List _makeArray(int length) { return List.filled(length, null); } -/// This helper method becomes an noop when compiled with dart2js on +/// This helper method becomes an no-op when compiled with dart2js on /// with high level of optimizations enabled. @pragma('dart2js:tryInline') @pragma('dart2js:as:trust') diff --git a/packages/flutter/lib/src/foundation/service_extensions.dart b/packages/flutter/lib/src/foundation/service_extensions.dart new file mode 100644 index 0000000000000..54d6874d1e76f --- /dev/null +++ b/packages/flutter/lib/src/foundation/service_extensions.dart @@ -0,0 +1,77 @@ +// 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. + +/// Service extension constants for the foundation library. +/// +/// These constants will be used when registering service extensions in the +/// framework, and they will also be used by tools and services that call these +/// service extensions. +/// +/// The String value for each of these extension names should be accessed by +/// calling the `.name` property on the enum value. +enum FoundationServiceExtensions { + /// Name of service extension that, when called, will cause the entire + /// application to redraw. + /// + /// See also: + /// + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + reassemble, + + /// Name of service extension that, when called, will terminate the Flutter + /// application. + /// + /// See also: + /// + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + exit, + + /// Name of service extension that, when called, will get or set the value of + /// [connectedVmServiceUri]. + /// + /// See also: + /// + /// * [connectedVmServiceUri], which stores the uri for the connected vm service + /// protocol. + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + connectedVmServiceUri, + + /// Name of service extension that, when called, will get or set the value of + /// [activeDevToolsServerAddress]. + /// + /// See also: + /// + /// * [activeDevToolsServerAddress], which stores the address for the active + /// DevTools server used for debugging this application. + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + activeDevToolsServerAddress, + + + /// Name of service extension that, when called, will change the value of + /// [defaultTargetPlatform], which controls which [TargetPlatform] that the + /// framework will execute for. + /// + /// See also: + /// + /// * [debugDefaultTargetPlatformOverride], which is the flag that this service + /// extension exposes. + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + platformOverride, + + /// Name of service extension that, when called, will override the platform + /// [Brightness]. + /// + /// See also: + /// + /// * [debugBrightnessOverride], which is the flag that this service + /// extension exposes. + /// * [BindingBase.initServiceExtensions], where the service extension is + /// registered. + brightnessOverride, +} diff --git a/packages/flutter/lib/src/material/data_table.dart b/packages/flutter/lib/src/material/data_table.dart index 443c20a8b9fac..df8d3b4f34ae6 100644 --- a/packages/flutter/lib/src/material/data_table.dart +++ b/packages/flutter/lib/src/material/data_table.dart @@ -300,7 +300,7 @@ class DataCell { /// Called if the user cancels a tap was started on cell. /// - /// If non-null, cancelling the tap gesture will invoke this callback. + /// If non-null, canceling the tap gesture will invoke this callback. /// If null (including [onTap], [onDoubleTap] and [onLongPress]), /// tapping the cell will attempt to select the /// row (if [DataRow.onSelectChanged] is provided). diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index 405a579afb624..88df4399c502b 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -225,7 +225,7 @@ class Dialog extends StatelessWidget { /// A Material Design alert dialog. /// /// An alert dialog (also known as a basic dialog) informs the user about -/// situations that require acknowledgement. An alert dialog has an optional +/// situations that require acknowledgment. An alert dialog has an optional /// title and an optional list of actions. The title is displayed above the /// content and the actions are displayed below the content. /// diff --git a/packages/flutter/lib/src/material/icons.dart b/packages/flutter/lib/src/material/icons.dart index 8355ef34263e4..754ba917e1112 100644 --- a/packages/flutter/lib/src/material/icons.dart +++ b/packages/flutter/lib/src/material/icons.dart @@ -2298,6 +2298,18 @@ class Icons { /// arrow_left — material icon named "arrow left" (outlined). static const IconData arrow_left_outlined = IconData(0xee8e, fontFamily: 'MaterialIcons', matchTextDirection: true); + /// arrow_outward — material icon named "arrow outward". + static const IconData arrow_outward = IconData(0xf0852, fontFamily: 'MaterialIcons'); + + /// arrow_outward — material icon named "arrow outward" (sharp). + static const IconData arrow_outward_sharp = IconData(0xf0834, fontFamily: 'MaterialIcons'); + + /// arrow_outward — material icon named "arrow outward" (round). + static const IconData arrow_outward_rounded = IconData(0xf087d, fontFamily: 'MaterialIcons'); + + /// arrow_outward — material icon named "arrow outward" (outlined). + static const IconData arrow_outward_outlined = IconData(0xf089b, fontFamily: 'MaterialIcons'); + /// arrow_right — material icon named "arrow right". static const IconData arrow_right = IconData(0xe09e, fontFamily: 'MaterialIcons', matchTextDirection: true); @@ -2394,6 +2406,9 @@ class Icons { /// assignment — material icon named "assignment" (outlined). static const IconData assignment_outlined = IconData(0xee98, fontFamily: 'MaterialIcons', matchTextDirection: true); + /// assignment_add — material icon named "assignment add". + static const IconData assignment_add = IconData(0xf0853, fontFamily: 'MaterialIcons'); + /// assignment_ind — material icon named "assignment ind". static const IconData assignment_ind = IconData(0xe0a6, fontFamily: 'MaterialIcons'); @@ -2454,6 +2469,18 @@ class Icons { /// assignment_turned_in — material icon named "assignment turned in" (outlined). static const IconData assignment_turned_in_outlined = IconData(0xee9b, fontFamily: 'MaterialIcons'); + /// assist_walker — material icon named "assist walker". + static const IconData assist_walker = IconData(0xf0854, fontFamily: 'MaterialIcons'); + + /// assist_walker — material icon named "assist walker" (sharp). + static const IconData assist_walker_sharp = IconData(0xf0835, fontFamily: 'MaterialIcons'); + + /// assist_walker — material icon named "assist walker" (round). + static const IconData assist_walker_rounded = IconData(0xf087e, fontFamily: 'MaterialIcons'); + + /// assist_walker — material icon named "assist walker" (outlined). + static const IconData assist_walker_outlined = IconData(0xf089c, fontFamily: 'MaterialIcons'); + /// assistant — material icon named "assistant". static const IconData assistant = IconData(0xe0ab, fontFamily: 'MaterialIcons'); @@ -2913,6 +2940,9 @@ class Icons { /// bar_chart — material icon named "bar chart" (outlined). static const IconData bar_chart_outlined = IconData(0xeebc, fontFamily: 'MaterialIcons'); + /// barcode_reader — material icon named "barcode reader". + static const IconData barcode_reader = IconData(0xf0855, fontFamily: 'MaterialIcons'); + /// batch_prediction — material icon named "batch prediction". static const IconData batch_prediction = IconData(0xe0cd, fontFamily: 'MaterialIcons'); @@ -3249,6 +3279,18 @@ class Icons { /// blender — material icon named "blender" (outlined). static const IconData blender_outlined = IconData(0xeed0, fontFamily: 'MaterialIcons'); + /// blind — material icon named "blind". + static const IconData blind = IconData(0xf0856, fontFamily: 'MaterialIcons'); + + /// blind — material icon named "blind" (sharp). + static const IconData blind_sharp = IconData(0xf0836, fontFamily: 'MaterialIcons'); + + /// blind — material icon named "blind" (round). + static const IconData blind_rounded = IconData(0xf087f, fontFamily: 'MaterialIcons'); + + /// blind — material icon named "blind" (outlined). + static const IconData blind_outlined = IconData(0xf089d, fontFamily: 'MaterialIcons'); + /// blinds — material icon named "blinds". static const IconData blinds = IconData(0xf078f, fontFamily: 'MaterialIcons'); @@ -5535,6 +5577,18 @@ class Icons { /// construction — material icon named "construction" (outlined). static const IconData construction_outlined = IconData(0xef78, fontFamily: 'MaterialIcons'); + /// contact_emergency — material icon named "contact emergency". + static const IconData contact_emergency = IconData(0xf0857, fontFamily: 'MaterialIcons'); + + /// contact_emergency — material icon named "contact emergency" (sharp). + static const IconData contact_emergency_sharp = IconData(0xf0837, fontFamily: 'MaterialIcons'); + + /// contact_emergency — material icon named "contact emergency" (round). + static const IconData contact_emergency_rounded = IconData(0xf0880, fontFamily: 'MaterialIcons'); + + /// contact_emergency — material icon named "contact emergency" (outlined). + static const IconData contact_emergency_outlined = IconData(0xf089e, fontFamily: 'MaterialIcons'); + /// contact_mail — material icon named "contact mail". static const IconData contact_mail = IconData(0xe18a, fontFamily: 'MaterialIcons'); @@ -5727,6 +5781,9 @@ class Icons { /// control_point_duplicate — material icon named "control point duplicate" (outlined). static const IconData control_point_duplicate_outlined = IconData(0xef84, fontFamily: 'MaterialIcons'); + /// conveyor_belt — material icon named "conveyor belt". + static const IconData conveyor_belt = IconData(0xf0858, fontFamily: 'MaterialIcons'); + /// cookie — material icon named "cookie". static const IconData cookie = IconData(0xf04d9, fontFamily: 'MaterialIcons'); @@ -6747,6 +6804,9 @@ class Icons { /// devices_other — material icon named "devices other" (outlined). static const IconData devices_other_outlined = IconData(0xefba, fontFamily: 'MaterialIcons'); + /// dew_point — material icon named "dew point". + static const IconData dew_point = IconData(0xf0859, fontFamily: 'MaterialIcons'); + /// dialer_sip — material icon named "dialer sip". static const IconData dialer_sip = IconData(0xe1cd, fontFamily: 'MaterialIcons'); @@ -7131,6 +7191,42 @@ class Icons { /// display_settings — material icon named "display settings" (outlined). static const IconData display_settings_outlined = IconData(0xf05eb, fontFamily: 'MaterialIcons'); + /// diversity_1 — material icon named "diversity 1". + static const IconData diversity_1 = IconData(0xf085a, fontFamily: 'MaterialIcons'); + + /// diversity_1 — material icon named "diversity 1" (sharp). + static const IconData diversity_1_sharp = IconData(0xf0838, fontFamily: 'MaterialIcons'); + + /// diversity_1 — material icon named "diversity 1" (round). + static const IconData diversity_1_rounded = IconData(0xf0881, fontFamily: 'MaterialIcons'); + + /// diversity_1 — material icon named "diversity 1" (outlined). + static const IconData diversity_1_outlined = IconData(0xf089f, fontFamily: 'MaterialIcons'); + + /// diversity_2 — material icon named "diversity 2". + static const IconData diversity_2 = IconData(0xf085b, fontFamily: 'MaterialIcons'); + + /// diversity_2 — material icon named "diversity 2" (sharp). + static const IconData diversity_2_sharp = IconData(0xf0839, fontFamily: 'MaterialIcons'); + + /// diversity_2 — material icon named "diversity 2" (round). + static const IconData diversity_2_rounded = IconData(0xf0882, fontFamily: 'MaterialIcons'); + + /// diversity_2 — material icon named "diversity 2" (outlined). + static const IconData diversity_2_outlined = IconData(0xf08a0, fontFamily: 'MaterialIcons'); + + /// diversity_3 — material icon named "diversity 3". + static const IconData diversity_3 = IconData(0xf085c, fontFamily: 'MaterialIcons'); + + /// diversity_3 — material icon named "diversity 3" (sharp). + static const IconData diversity_3_sharp = IconData(0xf083a, fontFamily: 'MaterialIcons'); + + /// diversity_3 — material icon named "diversity 3" (round). + static const IconData diversity_3_rounded = IconData(0xf0883, fontFamily: 'MaterialIcons'); + + /// diversity_3 — material icon named "diversity 3" (outlined). + static const IconData diversity_3_outlined = IconData(0xf08a1, fontFamily: 'MaterialIcons'); + /// dnd_forwardslash — material icon named "dnd forwardslash". static const IconData dnd_forwardslash = IconData(0xe1eb, fontFamily: 'MaterialIcons'); @@ -7842,6 +7938,9 @@ class Icons { /// edit_calendar — material icon named "edit calendar" (outlined). static const IconData edit_calendar_outlined = IconData(0xf05ef, fontFamily: 'MaterialIcons'); + /// edit_document — material icon named "edit document". + static const IconData edit_document = IconData(0xf085d, fontFamily: 'MaterialIcons'); + /// edit_location — material icon named "edit location". static const IconData edit_location = IconData(0xe21c, fontFamily: 'MaterialIcons'); @@ -7914,6 +8013,9 @@ class Icons { /// edit_road — material icon named "edit road" (outlined). static const IconData edit_road_outlined = IconData(0xf00e, fontFamily: 'MaterialIcons'); + /// edit_square — material icon named "edit square". + static const IconData edit_square = IconData(0xf085e, fontFamily: 'MaterialIcons'); + /// egg — material icon named "egg". static const IconData egg = IconData(0xf04f8, fontFamily: 'MaterialIcons'); @@ -8682,6 +8784,66 @@ class Icons { /// face — material icon named "face" (outlined). static const IconData face_outlined = IconData(0xf040, fontFamily: 'MaterialIcons'); + /// face_2 — material icon named "face 2". + static const IconData face_2 = IconData(0xf085f, fontFamily: 'MaterialIcons'); + + /// face_2 — material icon named "face 2" (sharp). + static const IconData face_2_sharp = IconData(0xf083b, fontFamily: 'MaterialIcons'); + + /// face_2 — material icon named "face 2" (round). + static const IconData face_2_rounded = IconData(0xf0884, fontFamily: 'MaterialIcons'); + + /// face_2 — material icon named "face 2" (outlined). + static const IconData face_2_outlined = IconData(0xf08a2, fontFamily: 'MaterialIcons'); + + /// face_3 — material icon named "face 3". + static const IconData face_3 = IconData(0xf0860, fontFamily: 'MaterialIcons'); + + /// face_3 — material icon named "face 3" (sharp). + static const IconData face_3_sharp = IconData(0xf083c, fontFamily: 'MaterialIcons'); + + /// face_3 — material icon named "face 3" (round). + static const IconData face_3_rounded = IconData(0xf0885, fontFamily: 'MaterialIcons'); + + /// face_3 — material icon named "face 3" (outlined). + static const IconData face_3_outlined = IconData(0xf08a3, fontFamily: 'MaterialIcons'); + + /// face_4 — material icon named "face 4". + static const IconData face_4 = IconData(0xf0861, fontFamily: 'MaterialIcons'); + + /// face_4 — material icon named "face 4" (sharp). + static const IconData face_4_sharp = IconData(0xf083d, fontFamily: 'MaterialIcons'); + + /// face_4 — material icon named "face 4" (round). + static const IconData face_4_rounded = IconData(0xf0886, fontFamily: 'MaterialIcons'); + + /// face_4 — material icon named "face 4" (outlined). + static const IconData face_4_outlined = IconData(0xf08a4, fontFamily: 'MaterialIcons'); + + /// face_5 — material icon named "face 5". + static const IconData face_5 = IconData(0xf0862, fontFamily: 'MaterialIcons'); + + /// face_5 — material icon named "face 5" (sharp). + static const IconData face_5_sharp = IconData(0xf083e, fontFamily: 'MaterialIcons'); + + /// face_5 — material icon named "face 5" (round). + static const IconData face_5_rounded = IconData(0xf0887, fontFamily: 'MaterialIcons'); + + /// face_5 — material icon named "face 5" (outlined). + static const IconData face_5_outlined = IconData(0xf08a5, fontFamily: 'MaterialIcons'); + + /// face_6 — material icon named "face 6". + static const IconData face_6 = IconData(0xf0863, fontFamily: 'MaterialIcons'); + + /// face_6 — material icon named "face 6" (sharp). + static const IconData face_6_sharp = IconData(0xf083f, fontFamily: 'MaterialIcons'); + + /// face_6 — material icon named "face 6" (round). + static const IconData face_6_rounded = IconData(0xf0888, fontFamily: 'MaterialIcons'); + + /// face_6 — material icon named "face 6" (outlined). + static const IconData face_6_outlined = IconData(0xf08a6, fontFamily: 'MaterialIcons'); + /// face_retouching_natural — material icon named "face retouching natural". static const IconData face_retouching_natural = IconData(0xe253, fontFamily: 'MaterialIcons'); @@ -9075,6 +9237,9 @@ class Icons { /// file_upload — material icon named "file upload" (outlined). static const IconData file_upload_outlined = IconData(0xf05d, fontFamily: 'MaterialIcons'); + /// file_upload_off — material icon named "file upload off". + static const IconData file_upload_off = IconData(0xf0864, fontFamily: 'MaterialIcons'); + /// filter — material icon named "filter". static const IconData filter = IconData(0xe26f, fontFamily: 'MaterialIcons'); @@ -9730,16 +9895,28 @@ class Icons { static const IconData flood_outlined = IconData(0xf06f3, fontFamily: 'MaterialIcons'); /// flourescent — material icon named "flourescent". - static const IconData flourescent = IconData(0xe29f, fontFamily: 'MaterialIcons'); + static const IconData flourescent = IconData(0xf0865, fontFamily: 'MaterialIcons'); /// flourescent — material icon named "flourescent" (sharp). - static const IconData flourescent_sharp = IconData(0xe99a, fontFamily: 'MaterialIcons'); + static const IconData flourescent_sharp = IconData(0xf0840, fontFamily: 'MaterialIcons'); /// flourescent — material icon named "flourescent" (round). - static const IconData flourescent_rounded = IconData(0xf779, fontFamily: 'MaterialIcons'); + static const IconData flourescent_rounded = IconData(0xf0889, fontFamily: 'MaterialIcons'); /// flourescent — material icon named "flourescent" (outlined). - static const IconData flourescent_outlined = IconData(0xf08c, fontFamily: 'MaterialIcons'); + static const IconData flourescent_outlined = IconData(0xf08a7, fontFamily: 'MaterialIcons'); + + /// fluorescent — material icon named "fluorescent". + static const IconData fluorescent = IconData(0xf0865, fontFamily: 'MaterialIcons'); + + /// fluorescent — material icon named "fluorescent" (sharp). + static const IconData fluorescent_sharp = IconData(0xf0840, fontFamily: 'MaterialIcons'); + + /// fluorescent — material icon named "fluorescent" (round). + static const IconData fluorescent_rounded = IconData(0xf0889, fontFamily: 'MaterialIcons'); + + /// fluorescent — material icon named "fluorescent" (outlined). + static const IconData fluorescent_outlined = IconData(0xf08a7, fontFamily: 'MaterialIcons'); /// flutter_dash — material icon named "flutter dash". static const IconData flutter_dash = IconData(0xe2a0, fontFamily: 'MaterialIcons'); @@ -9960,6 +10137,9 @@ class Icons { /// fork_right — material icon named "fork right" (outlined). static const IconData fork_right_outlined = IconData(0xf0605, fontFamily: 'MaterialIcons'); + /// forklift — material icon named "forklift". + static const IconData forklift = IconData(0xf0866, fontFamily: 'MaterialIcons'); + /// format_align_center — material icon named "format align center". static const IconData format_align_center = IconData(0xe2ab, fontFamily: 'MaterialIcons'); @@ -10128,6 +10308,9 @@ class Icons { /// format_list_bulleted — material icon named "format list bulleted" (outlined). static const IconData format_list_bulleted_outlined = IconData(0xf0a5, fontFamily: 'MaterialIcons', matchTextDirection: true); + /// format_list_bulleted_add — material icon named "format list bulleted add". + static const IconData format_list_bulleted_add = IconData(0xf0867, fontFamily: 'MaterialIcons'); + /// format_list_numbered — material icon named "format list numbered". static const IconData format_list_numbered = IconData(0xe2b9, fontFamily: 'MaterialIcons'); @@ -10404,6 +10587,9 @@ class Icons { /// front_hand — material icon named "front hand" (outlined). static const IconData front_hand_outlined = IconData(0xf0609, fontFamily: 'MaterialIcons'); + /// front_loader — material icon named "front loader". + static const IconData front_loader = IconData(0xf0868, fontFamily: 'MaterialIcons'); + /// fullscreen — material icon named "fullscreen". static const IconData fullscreen = IconData(0xe2cb, fontFamily: 'MaterialIcons'); @@ -10908,6 +11094,30 @@ class Icons { /// groups — material icon named "groups" (outlined). static const IconData groups_outlined = IconData(0xf0db, fontFamily: 'MaterialIcons'); + /// groups_2 — material icon named "groups 2". + static const IconData groups_2 = IconData(0xf0869, fontFamily: 'MaterialIcons'); + + /// groups_2 — material icon named "groups 2" (sharp). + static const IconData groups_2_sharp = IconData(0xf0841, fontFamily: 'MaterialIcons'); + + /// groups_2 — material icon named "groups 2" (round). + static const IconData groups_2_rounded = IconData(0xf088a, fontFamily: 'MaterialIcons'); + + /// groups_2 — material icon named "groups 2" (outlined). + static const IconData groups_2_outlined = IconData(0xf08a8, fontFamily: 'MaterialIcons'); + + /// groups_3 — material icon named "groups 3". + static const IconData groups_3 = IconData(0xf086a, fontFamily: 'MaterialIcons'); + + /// groups_3 — material icon named "groups 3" (sharp). + static const IconData groups_3_sharp = IconData(0xf0842, fontFamily: 'MaterialIcons'); + + /// groups_3 — material icon named "groups 3" (round). + static const IconData groups_3_rounded = IconData(0xf088b, fontFamily: 'MaterialIcons'); + + /// groups_3 — material icon named "groups 3" (outlined). + static const IconData groups_3_outlined = IconData(0xf08a9, fontFamily: 'MaterialIcons'); + /// h_mobiledata — material icon named "h mobiledata". static const IconData h_mobiledata = IconData(0xe2ef, fontFamily: 'MaterialIcons'); @@ -13980,6 +14190,18 @@ class Icons { /// lyrics — material icon named "lyrics" (outlined). static const IconData lyrics_outlined = IconData(0xf06f9, fontFamily: 'MaterialIcons'); + /// macro_off — material icon named "macro off". + static const IconData macro_off = IconData(0xf086b, fontFamily: 'MaterialIcons'); + + /// macro_off — material icon named "macro off" (sharp). + static const IconData macro_off_sharp = IconData(0xf0843, fontFamily: 'MaterialIcons'); + + /// macro_off — material icon named "macro off" (round). + static const IconData macro_off_rounded = IconData(0xf088c, fontFamily: 'MaterialIcons'); + + /// macro_off — material icon named "macro off" (outlined). + static const IconData macro_off_outlined = IconData(0xf08aa, fontFamily: 'MaterialIcons'); + /// mail — material icon named "mail". static const IconData mail = IconData(0xe3c3, fontFamily: 'MaterialIcons'); @@ -14040,6 +14262,42 @@ class Icons { /// man — material icon named "man" (outlined). static const IconData man_outlined = IconData(0xf0630, fontFamily: 'MaterialIcons'); + /// man_2 — material icon named "man 2". + static const IconData man_2 = IconData(0xf086c, fontFamily: 'MaterialIcons'); + + /// man_2 — material icon named "man 2" (sharp). + static const IconData man_2_sharp = IconData(0xf0844, fontFamily: 'MaterialIcons'); + + /// man_2 — material icon named "man 2" (round). + static const IconData man_2_rounded = IconData(0xf088d, fontFamily: 'MaterialIcons'); + + /// man_2 — material icon named "man 2" (outlined). + static const IconData man_2_outlined = IconData(0xf08ab, fontFamily: 'MaterialIcons'); + + /// man_3 — material icon named "man 3". + static const IconData man_3 = IconData(0xf086d, fontFamily: 'MaterialIcons'); + + /// man_3 — material icon named "man 3" (sharp). + static const IconData man_3_sharp = IconData(0xf0845, fontFamily: 'MaterialIcons'); + + /// man_3 — material icon named "man 3" (round). + static const IconData man_3_rounded = IconData(0xf088e, fontFamily: 'MaterialIcons'); + + /// man_3 — material icon named "man 3" (outlined). + static const IconData man_3_outlined = IconData(0xf08ac, fontFamily: 'MaterialIcons'); + + /// man_4 — material icon named "man 4". + static const IconData man_4 = IconData(0xf086e, fontFamily: 'MaterialIcons'); + + /// man_4 — material icon named "man 4" (sharp). + static const IconData man_4_sharp = IconData(0xf0846, fontFamily: 'MaterialIcons'); + + /// man_4 — material icon named "man 4" (round). + static const IconData man_4_rounded = IconData(0xf088f, fontFamily: 'MaterialIcons'); + + /// man_4 — material icon named "man 4" (outlined). + static const IconData man_4_outlined = IconData(0xf08ad, fontFamily: 'MaterialIcons'); + /// manage_accounts — material icon named "manage accounts". static const IconData manage_accounts = IconData(0xe3c6, fontFamily: 'MaterialIcons'); @@ -15084,6 +15342,9 @@ class Icons { /// movie_creation — material icon named "movie creation" (outlined). static const IconData movie_creation_outlined = IconData(0xf1f3, fontFamily: 'MaterialIcons'); + /// movie_edit — material icon named "movie edit". + static const IconData movie_edit = IconData(0xf08b9, fontFamily: 'MaterialIcons'); + /// movie_filter — material icon named "movie filter". static const IconData movie_filter = IconData(0xe40f, fontFamily: 'MaterialIcons'); @@ -16434,6 +16695,9 @@ class Icons { /// palette — material icon named "palette" (outlined). static const IconData palette_outlined = IconData(0xf24f, fontFamily: 'MaterialIcons'); + /// pallet — material icon named "pallet". + static const IconData pallet = IconData(0xf086f, fontFamily: 'MaterialIcons'); + /// pan_tool — material icon named "pan tool". static const IconData pan_tool = IconData(0xe46c, fontFamily: 'MaterialIcons'); @@ -16986,6 +17250,42 @@ class Icons { /// person — material icon named "person" (outlined). static const IconData person_outlined = IconData(0xf27b, fontFamily: 'MaterialIcons'); + /// person_2 — material icon named "person 2". + static const IconData person_2 = IconData(0xf0870, fontFamily: 'MaterialIcons'); + + /// person_2 — material icon named "person 2" (sharp). + static const IconData person_2_sharp = IconData(0xf0847, fontFamily: 'MaterialIcons'); + + /// person_2 — material icon named "person 2" (round). + static const IconData person_2_rounded = IconData(0xf0890, fontFamily: 'MaterialIcons'); + + /// person_2 — material icon named "person 2" (outlined). + static const IconData person_2_outlined = IconData(0xf08ae, fontFamily: 'MaterialIcons'); + + /// person_3 — material icon named "person 3". + static const IconData person_3 = IconData(0xf0871, fontFamily: 'MaterialIcons'); + + /// person_3 — material icon named "person 3" (sharp). + static const IconData person_3_sharp = IconData(0xf0848, fontFamily: 'MaterialIcons'); + + /// person_3 — material icon named "person 3" (round). + static const IconData person_3_rounded = IconData(0xf0891, fontFamily: 'MaterialIcons'); + + /// person_3 — material icon named "person 3" (outlined). + static const IconData person_3_outlined = IconData(0xf08af, fontFamily: 'MaterialIcons'); + + /// person_4 — material icon named "person 4". + static const IconData person_4 = IconData(0xf0872, fontFamily: 'MaterialIcons'); + + /// person_4 — material icon named "person 4" (sharp). + static const IconData person_4_sharp = IconData(0xf0849, fontFamily: 'MaterialIcons'); + + /// person_4 — material icon named "person 4" (round). + static const IconData person_4_rounded = IconData(0xf0892, fontFamily: 'MaterialIcons'); + + /// person_4 — material icon named "person 4" (outlined). + static const IconData person_4_outlined = IconData(0xf08b0, fontFamily: 'MaterialIcons'); + /// person_add — material icon named "person add". static const IconData person_add = IconData(0xe492, fontFamily: 'MaterialIcons'); @@ -18267,6 +18567,18 @@ class Icons { /// psychology — material icon named "psychology" (outlined). static const IconData psychology_outlined = IconData(0xf2d2, fontFamily: 'MaterialIcons'); + /// psychology_alt — material icon named "psychology alt". + static const IconData psychology_alt = IconData(0xf0873, fontFamily: 'MaterialIcons'); + + /// psychology_alt — material icon named "psychology alt" (sharp). + static const IconData psychology_alt_sharp = IconData(0xf084a, fontFamily: 'MaterialIcons'); + + /// psychology_alt — material icon named "psychology alt" (round). + static const IconData psychology_alt_rounded = IconData(0xf0893, fontFamily: 'MaterialIcons'); + + /// psychology_alt — material icon named "psychology alt" (outlined). + static const IconData psychology_alt_outlined = IconData(0xf08b1, fontFamily: 'MaterialIcons'); + /// public — material icon named "public". static const IconData public = IconData(0xe4f0, fontFamily: 'MaterialIcons'); @@ -18711,6 +19023,9 @@ class Icons { /// real_estate_agent — material icon named "real estate agent" (outlined). static const IconData real_estate_agent_outlined = IconData(0xf2ee, fontFamily: 'MaterialIcons'); + /// rebase_edit — material icon named "rebase edit". + static const IconData rebase_edit = IconData(0xf0874, fontFamily: 'MaterialIcons'); + /// receipt — material icon named "receipt". static const IconData receipt = IconData(0xe50c, fontFamily: 'MaterialIcons'); @@ -18987,6 +19302,18 @@ class Icons { /// reorder — material icon named "reorder" (outlined). static const IconData reorder_outlined = IconData(0xf301, fontFamily: 'MaterialIcons'); + /// repartition — material icon named "repartition". + static const IconData repartition = IconData(0xf0875, fontFamily: 'MaterialIcons'); + + /// repartition — material icon named "repartition" (sharp). + static const IconData repartition_sharp = IconData(0xf084b, fontFamily: 'MaterialIcons'); + + /// repartition — material icon named "repartition" (round). + static const IconData repartition_rounded = IconData(0xf0894, fontFamily: 'MaterialIcons'); + + /// repartition — material icon named "repartition" (outlined). + static const IconData repartition_outlined = IconData(0xf08b2, fontFamily: 'MaterialIcons'); + /// repeat — material icon named "repeat". static const IconData repeat = IconData(0xe51f, fontFamily: 'MaterialIcons'); @@ -20631,6 +20958,18 @@ class Icons { /// severe_cold — material icon named "severe cold" (outlined). static const IconData severe_cold_outlined = IconData(0xf0712, fontFamily: 'MaterialIcons'); + /// shape_line — material icon named "shape line". + static const IconData shape_line = IconData(0xf0876, fontFamily: 'MaterialIcons'); + + /// shape_line — material icon named "shape line" (sharp). + static const IconData shape_line_sharp = IconData(0xf084c, fontFamily: 'MaterialIcons'); + + /// shape_line — material icon named "shape line" (round). + static const IconData shape_line_rounded = IconData(0xf0895, fontFamily: 'MaterialIcons'); + + /// shape_line — material icon named "shape line" (outlined). + static const IconData shape_line_outlined = IconData(0xf08b3, fontFamily: 'MaterialIcons'); + /// share — material icon named "share". static const IconData share = IconData(0xe593, fontFamily: 'MaterialIcons'); @@ -20667,6 +21006,9 @@ class Icons { /// share_location — material icon named "share location" (outlined). static const IconData share_location_outlined = IconData(0xf377, fontFamily: 'MaterialIcons'); + /// shelves — material icon named "shelves". + static const IconData shelves = IconData(0xf0877, fontFamily: 'MaterialIcons'); + /// shield — material icon named "shield". static const IconData shield = IconData(0xe596, fontFamily: 'MaterialIcons'); @@ -24144,6 +24486,9 @@ class Icons { /// trip_origin — material icon named "trip origin" (outlined). static const IconData trip_origin_outlined = IconData(0xf463, fontFamily: 'MaterialIcons'); + /// trolley — material icon named "trolley". + static const IconData trolley = IconData(0xf0878, fontFamily: 'MaterialIcons'); + /// troubleshoot — material icon named "troubleshoot". static const IconData troubleshoot = IconData(0xf07ce, fontFamily: 'MaterialIcons'); @@ -24432,6 +24777,18 @@ class Icons { /// unfold_less — material icon named "unfold less" (outlined). static const IconData unfold_less_outlined = IconData(0xf470, fontFamily: 'MaterialIcons'); + /// unfold_less_double — material icon named "unfold less double". + static const IconData unfold_less_double = IconData(0xf0879, fontFamily: 'MaterialIcons'); + + /// unfold_less_double — material icon named "unfold less double" (sharp). + static const IconData unfold_less_double_sharp = IconData(0xf084d, fontFamily: 'MaterialIcons'); + + /// unfold_less_double — material icon named "unfold less double" (round). + static const IconData unfold_less_double_rounded = IconData(0xf0896, fontFamily: 'MaterialIcons'); + + /// unfold_less_double — material icon named "unfold less double" (outlined). + static const IconData unfold_less_double_outlined = IconData(0xf08b4, fontFamily: 'MaterialIcons'); + /// unfold_more — material icon named "unfold more". static const IconData unfold_more = IconData(0xe68e, fontFamily: 'MaterialIcons'); @@ -24444,6 +24801,18 @@ class Icons { /// unfold_more — material icon named "unfold more" (outlined). static const IconData unfold_more_outlined = IconData(0xf471, fontFamily: 'MaterialIcons'); + /// unfold_more_double — material icon named "unfold more double". + static const IconData unfold_more_double = IconData(0xf087a, fontFamily: 'MaterialIcons'); + + /// unfold_more_double — material icon named "unfold more double" (sharp). + static const IconData unfold_more_double_sharp = IconData(0xf084e, fontFamily: 'MaterialIcons'); + + /// unfold_more_double — material icon named "unfold more double" (round). + static const IconData unfold_more_double_rounded = IconData(0xf0897, fontFamily: 'MaterialIcons'); + + /// unfold_more_double — material icon named "unfold more double" (outlined). + static const IconData unfold_more_double_outlined = IconData(0xf08b5, fontFamily: 'MaterialIcons'); + /// unpublished — material icon named "unpublished". static const IconData unpublished = IconData(0xe68f, fontFamily: 'MaterialIcons'); @@ -24756,6 +25125,18 @@ class Icons { /// video_camera_front — material icon named "video camera front" (outlined). static const IconData video_camera_front_outlined = IconData(0xf486, fontFamily: 'MaterialIcons'); + /// video_chat — material icon named "video chat". + static const IconData video_chat = IconData(0xf087b, fontFamily: 'MaterialIcons'); + + /// video_chat — material icon named "video chat" (sharp). + static const IconData video_chat_sharp = IconData(0xf084f, fontFamily: 'MaterialIcons'); + + /// video_chat — material icon named "video chat" (round). + static const IconData video_chat_rounded = IconData(0xf0898, fontFamily: 'MaterialIcons'); + + /// video_chat — material icon named "video chat" (outlined). + static const IconData video_chat_outlined = IconData(0xf08b6, fontFamily: 'MaterialIcons'); + /// video_collection — material icon named "video collection". static const IconData video_collection = IconData(0xe6a5, fontFamily: 'MaterialIcons'); @@ -25689,6 +26070,15 @@ class Icons { /// web_stories — material icon named "web stories". static const IconData web_stories = IconData(0xe6e0, fontFamily: 'MaterialIcons'); + /// web_stories — material icon named "web stories" (sharp). + static const IconData web_stories_sharp = IconData(0xf0850, fontFamily: 'MaterialIcons'); + + /// web_stories — material icon named "web stories" (round). + static const IconData web_stories_rounded = IconData(0xf0899, fontFamily: 'MaterialIcons'); + + /// web_stories — material icon named "web stories" (outlined). + static const IconData web_stories_outlined = IconData(0xf08b7, fontFamily: 'MaterialIcons'); + /// webhook — material icon named "webhook". static const IconData webhook = IconData(0xf05a4, fontFamily: 'MaterialIcons'); @@ -25737,18 +26127,6 @@ class Icons { /// west — material icon named "west" (outlined). static const IconData west_outlined = IconData(0xf4c3, fontFamily: 'MaterialIcons'); - /// whatsapp — material icon named "whatsapp". - static const IconData whatsapp = IconData(0xf05a6, fontFamily: 'MaterialIcons'); - - /// whatsapp — material icon named "whatsapp" (sharp). - static const IconData whatsapp_sharp = IconData(0xf04ab, fontFamily: 'MaterialIcons'); - - /// whatsapp — material icon named "whatsapp" (round). - static const IconData whatsapp_rounded = IconData(0xf03b8, fontFamily: 'MaterialIcons'); - - /// whatsapp — material icon named "whatsapp" (outlined). - static const IconData whatsapp_outlined = IconData(0xf0699, fontFamily: 'MaterialIcons'); - /// whatshot — material icon named "whatshot". static const IconData whatshot = IconData(0xe6e3, fontFamily: 'MaterialIcons'); @@ -26058,6 +26436,18 @@ class Icons { /// woman — material icon named "woman" (outlined). static const IconData woman_outlined = IconData(0xf069e, fontFamily: 'MaterialIcons'); + /// woman_2 — material icon named "woman 2". + static const IconData woman_2 = IconData(0xf087c, fontFamily: 'MaterialIcons'); + + /// woman_2 — material icon named "woman 2" (sharp). + static const IconData woman_2_sharp = IconData(0xf0851, fontFamily: 'MaterialIcons'); + + /// woman_2 — material icon named "woman 2" (round). + static const IconData woman_2_rounded = IconData(0xf089a, fontFamily: 'MaterialIcons'); + + /// woman_2 — material icon named "woman 2" (outlined). + static const IconData woman_2_outlined = IconData(0xf08b8, fontFamily: 'MaterialIcons'); + /// woo_commerce — material icon named "woo commerce". static const IconData woo_commerce = IconData(0xf05ac, fontFamily: 'MaterialIcons'); diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index cceb50d175458..76e21deadb388 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -2892,7 +2892,7 @@ class InputDecoration { /// [icon] and above the widgets that contain [helperText], /// [errorText], and [counterText]. /// - /// The prefix icon aligment can be changed using [Align] with a fixed `widthFactor` and + /// The prefix icon alignment can be changed using [Align] with a fixed `widthFactor` and /// `heightFactor`. /// /// {@tool dartpad} @@ -3014,7 +3014,7 @@ class InputDecoration { /// [icon] and above the widgets that contain [helperText], /// [errorText], and [counterText]. /// - /// The suffix icon aligment can be changed using [Align] with a fixed `widthFactor` and + /// The suffix icon alignment can be changed using [Align] with a fixed `widthFactor` and /// `heightFactor`. /// /// {@tool dartpad} diff --git a/packages/flutter/lib/src/material/magnifier.dart b/packages/flutter/lib/src/material/magnifier.dart index 818081b740d7e..d25cad7f120db 100644 --- a/packages/flutter/lib/src/material/magnifier.dart +++ b/packages/flutter/lib/src/material/magnifier.dart @@ -286,7 +286,7 @@ class Magnifier extends StatelessWidget { /// The vertical distance that the magnifier should be above the focal point. /// /// [kStandardVerticalFocalPointShift] is an unmodifiable constant so that positioning of this - /// [Magnifier] can be done with a garunteed size, as opposed to an estimate. + /// [Magnifier] can be done with a guaranteed size, as opposed to an estimate. @visibleForTesting static const double kStandardVerticalFocalPointShift = 22; diff --git a/packages/flutter/lib/src/material/selectable_text.dart b/packages/flutter/lib/src/material/selectable_text.dart index f2ea90cca98c6..30e988ce7f3f1 100644 --- a/packages/flutter/lib/src/material/selectable_text.dart +++ b/packages/flutter/lib/src/material/selectable_text.dart @@ -440,9 +440,9 @@ class SelectableText extends StatefulWidget { /// /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details} /// - /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] on - /// Android, and builds nothing on all other platforms. If it is desired to supress - /// the magnifier, consider passing [TextMagnifierConfiguration.disabled]. + /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] + /// on Android, and builds nothing on all other platforms. If it is desired to + /// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled]. final TextMagnifierConfiguration? magnifierConfiguration; @override diff --git a/packages/flutter/lib/src/material/selection_area.dart b/packages/flutter/lib/src/material/selection_area.dart index 7c5daafb863a3..a02190c028e33 100644 --- a/packages/flutter/lib/src/material/selection_area.dart +++ b/packages/flutter/lib/src/material/selection_area.dart @@ -52,9 +52,9 @@ class SelectionArea extends StatefulWidget { /// /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details} /// - /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] on - /// Android, and builds nothing on all other platforms. If it is desired to supress - /// the magnifier, consider passing [TextMagnifierConfiguration.disabled]. + /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] + /// on Android, and builds nothing on all other platforms. If it is desired to + /// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled]. final TextMagnifierConfiguration? magnifierConfiguration; /// {@macro flutter.widgets.Focus.focusNode} diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index 19b69c20622ad..a17c0cef7d932 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -404,9 +404,9 @@ class TextField extends StatefulWidget { /// /// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details} /// - /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] on - /// Android, and builds nothing on all other platforms. If it is desired to supress - /// the magnifier, consider passing [TextMagnifierConfiguration.disabled]. + /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] + /// on Android, and builds nothing on all other platforms. If it is desired to + /// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled]. final TextMagnifierConfiguration? magnifierConfiguration; /// Controls the text being edited. diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index 305b8da54fd92..2f876bf158dba 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -295,7 +295,6 @@ class ThemeData with Diagnosticable { // [colorScheme] is the preferred way to configure colors. The other color // properties (as well as primaryColorBrightness, and primarySwatch) // will gradually be phased out, see https://github.com/flutter/flutter/issues/91772. - Color? bottomAppBarColor, Brightness? brightness, Color? canvasColor, Color? cardColor, @@ -432,6 +431,11 @@ class ThemeData with Diagnosticable { 'This feature was deprecated after v3.3.0-0.5.pre.', ) Color? backgroundColor, + @Deprecated( + 'Use BottomAppBarTheme.color instead. ' + 'This feature was deprecated after v3.3.0-0.6.pre.', + ) + Color? bottomAppBarColor, }) { // GENERAL CONFIGURATION cupertinoOverrideTheme = cupertinoOverrideTheme?.noDefault(); @@ -505,7 +509,6 @@ class ThemeData with Diagnosticable { shadowColor ??= Colors.black; canvasColor ??= isDark ? Colors.grey[850]! : Colors.grey[50]!; scaffoldBackgroundColor ??= canvasColor; - bottomAppBarColor ??= isDark ? Colors.grey[800]! : Colors.white; cardColor ??= isDark ? Colors.grey[800]! : Colors.white; dividerColor ??= isDark ? const Color(0x1FFFFFFF) : const Color(0x1F000000); // Create a ColorScheme that is backwards compatible as possible @@ -601,6 +604,7 @@ class ThemeData with Diagnosticable { primaryColorBrightness = estimatedPrimaryColorBrightness; errorColor ??= Colors.red[700]!; backgroundColor ??= isDark ? Colors.grey[700]! : primarySwatch[200]!; + bottomAppBarColor ??= colorSchemeSeed != null ? colorScheme.surface : isDark ? Colors.grey[800]! : Colors.white; return ThemeData.raw( // For the sanity of the reader, make sure these properties are in the same @@ -621,7 +625,6 @@ class ThemeData with Diagnosticable { useMaterial3: useMaterial3, visualDensity: visualDensity, // COLOR - bottomAppBarColor: bottomAppBarColor, canvasColor: canvasColor, cardColor: cardColor, colorScheme: colorScheme, @@ -696,6 +699,7 @@ class ThemeData with Diagnosticable { selectedRowColor: selectedRowColor, errorColor: errorColor, backgroundColor: backgroundColor, + bottomAppBarColor: bottomAppBarColor, ); } @@ -728,7 +732,6 @@ class ThemeData with Diagnosticable { // [colorScheme] is the preferred way to configure colors. The other color // properties will gradually be phased out, see // https://github.com/flutter/flutter/issues/91772. - required this.bottomAppBarColor, required this.canvasColor, required this.cardColor, required this.colorScheme, @@ -861,6 +864,12 @@ class ThemeData with Diagnosticable { 'This feature was deprecated after v3.3.0-0.5.pre.', ) Color? backgroundColor, + @Deprecated( + 'Use BottomAppBarTheme.color instead. ' + 'This feature was deprecated after v3.3.0-0.6.pre.', + ) + Color? bottomAppBarColor, + }) : // DEPRECATED (newest deprecations at the bottom) // should not be `required`, use getter pattern to avoid breakages. _accentColor = accentColor, @@ -874,6 +883,7 @@ class ThemeData with Diagnosticable { _selectedRowColor = selectedRowColor, _errorColor = errorColor, _backgroundColor = backgroundColor, + _bottomAppBarColor = bottomAppBarColor, // GENERAL CONFIGURATION assert(applyElevationOverlayColor != null), assert(extensions != null), @@ -886,7 +896,6 @@ class ThemeData with Diagnosticable { assert(useMaterial3 != null), assert(visualDensity != null), // COLOR - assert(bottomAppBarColor != null), assert(canvasColor != null), assert(cardColor != null), assert(colorScheme != null), @@ -1304,9 +1313,12 @@ class ThemeData with Diagnosticable { // COLOR /// The default color of the [BottomAppBar]. - /// - /// This can be overridden by specifying [BottomAppBar.color]. - final Color bottomAppBarColor; + @Deprecated( + 'Use BottomAppBarTheme.color instead. ' + 'This feature was deprecated after v3.3.0-0.6.pre.', + ) + Color get bottomAppBarColor => _bottomAppBarColor!; + final Color? _bottomAppBarColor; /// The default color of [MaterialType.canvas] [Material]. final Color canvasColor; @@ -1745,7 +1757,6 @@ class ThemeData with Diagnosticable { // [colorScheme] is the preferred way to configure colors. The other color // properties will gradually be phased out, see // https://github.com/flutter/flutter/issues/91772. - Color? bottomAppBarColor, Brightness? brightness, Color? canvasColor, Color? cardColor, @@ -1879,6 +1890,11 @@ class ThemeData with Diagnosticable { 'This feature was deprecated after v2.6.0-11.0.pre.', ) Color? backgroundColor, + @Deprecated( + 'Use BottomAppBarTheme.color instead. ' + 'This feature was deprecated after v3.3.0-0.6.pre.', + ) + Color? bottomAppBarColor, }) { cupertinoOverrideTheme = cupertinoOverrideTheme?.noDefault(); return ThemeData.raw( @@ -1900,7 +1916,6 @@ class ThemeData with Diagnosticable { useMaterial3: useMaterial3 ?? this.useMaterial3, visualDensity: visualDensity ?? this.visualDensity, // COLOR - bottomAppBarColor: bottomAppBarColor ?? this.bottomAppBarColor, canvasColor: canvasColor ?? this.canvasColor, cardColor: cardColor ?? this.cardColor, colorScheme: (colorScheme ?? this.colorScheme).copyWith(brightness: brightness), @@ -1975,6 +1990,7 @@ class ThemeData with Diagnosticable { selectedRowColor: selectedRowColor ?? _selectedRowColor, errorColor: errorColor ?? _errorColor, backgroundColor: backgroundColor ?? _backgroundColor, + bottomAppBarColor: bottomAppBarColor ?? _bottomAppBarColor, ); } @@ -2100,7 +2116,6 @@ class ThemeData with Diagnosticable { useMaterial3: t < 0.5 ? a.useMaterial3 : b.useMaterial3, visualDensity: VisualDensity.lerp(a.visualDensity, b.visualDensity, t), // COLOR - bottomAppBarColor: Color.lerp(a.bottomAppBarColor, b.bottomAppBarColor, t)!, canvasColor: Color.lerp(a.canvasColor, b.canvasColor, t)!, cardColor: Color.lerp(a.cardColor, b.cardColor, t)!, colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t), @@ -2175,6 +2190,7 @@ class ThemeData with Diagnosticable { selectedRowColor: Color.lerp(a.selectedRowColor, b.selectedRowColor, t), errorColor: Color.lerp(a.errorColor, b.errorColor, t), backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t), + bottomAppBarColor: Color.lerp(a.bottomAppBarColor, b.bottomAppBarColor, t), ); } @@ -2202,7 +2218,6 @@ class ThemeData with Diagnosticable { other.useMaterial3 == useMaterial3 && other.visualDensity == visualDensity && // COLOR - other.bottomAppBarColor == bottomAppBarColor && other.canvasColor == canvasColor && other.cardColor == cardColor && other.colorScheme == colorScheme && @@ -2276,7 +2291,8 @@ class ThemeData with Diagnosticable { other.toggleableActiveColor == toggleableActiveColor && other.selectedRowColor == selectedRowColor && other.errorColor == errorColor && - other.backgroundColor == backgroundColor; + other.backgroundColor == backgroundColor && + other.bottomAppBarColor == bottomAppBarColor; } @override @@ -2301,7 +2317,6 @@ class ThemeData with Diagnosticable { useMaterial3, visualDensity, // COLOR - bottomAppBarColor, canvasColor, cardColor, colorScheme, @@ -2376,6 +2391,7 @@ class ThemeData with Diagnosticable { selectedRowColor, errorColor, backgroundColor, + bottomAppBarColor, ]; return Object.hashAll(values); } @@ -2402,7 +2418,6 @@ class ThemeData with Diagnosticable { properties.add(DiagnosticsProperty('useMaterial3', useMaterial3, defaultValue: defaultData.useMaterial3, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty('visualDensity', visualDensity, defaultValue: defaultData.visualDensity, level: DiagnosticLevel.debug)); // COLORS - properties.add(ColorProperty('bottomAppBarColor', bottomAppBarColor, defaultValue: defaultData.bottomAppBarColor, level: DiagnosticLevel.debug)); properties.add(ColorProperty('canvasColor', canvasColor, defaultValue: defaultData.canvasColor, level: DiagnosticLevel.debug)); properties.add(ColorProperty('cardColor', cardColor, defaultValue: defaultData.cardColor, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty('colorScheme', colorScheme, defaultValue: defaultData.colorScheme, level: DiagnosticLevel.debug)); @@ -2477,6 +2492,7 @@ class ThemeData with Diagnosticable { properties.add(ColorProperty('selectedRowColor', selectedRowColor, defaultValue: defaultData.selectedRowColor, level: DiagnosticLevel.debug)); properties.add(ColorProperty('errorColor', errorColor, defaultValue: defaultData.errorColor, level: DiagnosticLevel.debug)); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor, level: DiagnosticLevel.debug)); + properties.add(ColorProperty('bottomAppBarColor', bottomAppBarColor, defaultValue: defaultData.bottomAppBarColor, level: DiagnosticLevel.debug)); } } diff --git a/packages/flutter/lib/src/painting/edge_insets.dart b/packages/flutter/lib/src/painting/edge_insets.dart index c2c38691cde94..756d79656d1a5 100644 --- a/packages/flutter/lib/src/painting/edge_insets.dart +++ b/packages/flutter/lib/src/painting/edge_insets.dart @@ -678,7 +678,7 @@ class EdgeInsetsDirectional extends EdgeInsetsGeometry { /// /// This is equivalent to [EdgeInsets.symmetric], since the inset is the same /// with either [TextDirection]. This constructor is just a convenience for - /// type compatibilty. + /// type compatibility. /// /// {@tool snippet} /// Eight pixel margin above and below, no horizontal margins: diff --git a/packages/flutter/lib/src/painting/image_provider.dart b/packages/flutter/lib/src/painting/image_provider.dart index cfb5a7f98aaa3..51bc1c63012c1 100644 --- a/packages/flutter/lib/src/painting/image_provider.dart +++ b/packages/flutter/lib/src/painting/image_provider.dart @@ -223,7 +223,7 @@ typedef DecoderBufferCallback = Future Function(ui.ImmutableBuffer buf /// image is decoded and ready to display, or when an error occurs. /// 2. Obtain the key for the image using [obtainKey]. /// Calling this method can throw exceptions into the zone asynchronously -/// or into the callstack synchronously. To handle that, an error handler +/// or into the call stack synchronously. To handle that, an error handler /// is created that catches both synchronous and asynchronous errors, to /// make sure errors can be routed to the correct consumers. /// The error handler is passed on to [resolveStreamForKey] and the diff --git a/packages/flutter/lib/src/painting/text_style.dart b/packages/flutter/lib/src/painting/text_style.dart index 81cc9f07be365..e6cc49938bace 100644 --- a/packages/flutter/lib/src/painting/text_style.dart +++ b/packages/flutter/lib/src/painting/text_style.dart @@ -1059,7 +1059,7 @@ class TextStyle with Diagnosticable { decorationThickness: other.decorationThickness, debugLabel: mergedDebugLabel, fontFamily: other._fontFamily, - fontFamilyFallback: other.fontFamilyFallback, + fontFamilyFallback: other._fontFamilyFallback, package: other._package, overflow: other.overflow, ); @@ -1116,7 +1116,7 @@ class TextStyle with Diagnosticable { decorationThickness: t < 0.5 ? null : b.decorationThickness, debugLabel: lerpDebugLabel, fontFamily: t < 0.5 ? null : b._fontFamily, - fontFamilyFallback: t < 0.5 ? null : b.fontFamilyFallback, + fontFamilyFallback: t < 0.5 ? null : b._fontFamilyFallback, package: t < 0.5 ? null : b._package, overflow: t < 0.5 ? null : b.overflow, ); @@ -1147,7 +1147,7 @@ class TextStyle with Diagnosticable { decorationThickness: t < 0.5 ? a.decorationThickness : null, debugLabel: lerpDebugLabel, fontFamily: t < 0.5 ? a._fontFamily : null, - fontFamilyFallback: t < 0.5 ? a.fontFamilyFallback : null, + fontFamilyFallback: t < 0.5 ? a._fontFamilyFallback : null, package: t < 0.5 ? a._package : null, overflow: t < 0.5 ? a.overflow : null, ); @@ -1185,7 +1185,7 @@ class TextStyle with Diagnosticable { decorationThickness: ui.lerpDouble(a.decorationThickness ?? b.decorationThickness, b.decorationThickness ?? a.decorationThickness, t), debugLabel: lerpDebugLabel, fontFamily: t < 0.5 ? a._fontFamily : b._fontFamily, - fontFamilyFallback: t < 0.5 ? a.fontFamilyFallback : b.fontFamilyFallback, + fontFamilyFallback: t < 0.5 ? a._fontFamilyFallback : b._fontFamilyFallback, package: t < 0.5 ? a._package : b._package, overflow: t < 0.5 ? a.overflow : b.overflow, ); diff --git a/packages/flutter/lib/src/rendering/binding.dart b/packages/flutter/lib/src/rendering/binding.dart index 23196536a817f..a9e0196063822 100644 --- a/packages/flutter/lib/src/rendering/binding.dart +++ b/packages/flutter/lib/src/rendering/binding.dart @@ -14,6 +14,7 @@ import 'box.dart'; import 'debug.dart'; import 'mouse_tracker.dart'; import 'object.dart'; +import 'service_extensions.dart'; import 'view.dart'; export 'package:flutter/gestures.dart' show HitTestResult; @@ -63,7 +64,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture assert(() { // these service extensions only work in debug mode registerBoolServiceExtension( - name: 'invertOversizedImages', + name: RenderingServiceExtensions.invertOversizedImages.name, getter: () async => debugInvertOversizedImages, setter: (bool value) async { if (debugInvertOversizedImages != value) { @@ -74,7 +75,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'debugPaint', + name: RenderingServiceExtensions.debugPaint.name, getter: () async => debugPaintSizeEnabled, setter: (bool value) { if (debugPaintSizeEnabled == value) { @@ -85,7 +86,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'debugPaintBaselinesEnabled', + name: RenderingServiceExtensions.debugPaintBaselinesEnabled.name, getter: () async => debugPaintBaselinesEnabled, setter: (bool value) { if (debugPaintBaselinesEnabled == value) { @@ -96,7 +97,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'repaintRainbow', + name: RenderingServiceExtensions.repaintRainbow.name, getter: () async => debugRepaintRainbowEnabled, setter: (bool value) { final bool repaint = debugRepaintRainbowEnabled && !value; @@ -108,7 +109,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerServiceExtension( - name: 'debugDumpLayerTree', + name: RenderingServiceExtensions.debugDumpLayerTree.name, callback: (Map parameters) async { final String data = RendererBinding.instance.renderView.debugLayer?.toStringDeep() ?? 'Layer tree unavailable.'; return { @@ -117,7 +118,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'debugDisableClipLayers', + name: RenderingServiceExtensions.debugDisableClipLayers.name, getter: () async => debugDisableClipLayers, setter: (bool value) { if (debugDisableClipLayers == value) { @@ -128,7 +129,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'debugDisablePhysicalShapeLayers', + name: RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, getter: () async => debugDisablePhysicalShapeLayers, setter: (bool value) { if (debugDisablePhysicalShapeLayers == value) { @@ -139,7 +140,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'debugDisableOpacityLayers', + name: RenderingServiceExtensions.debugDisableOpacityLayers.name, getter: () async => debugDisableOpacityLayers, setter: (bool value) { if (debugDisableOpacityLayers == value) { @@ -155,7 +156,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture if (!kReleaseMode) { // these service extensions work in debug or profile mode registerServiceExtension( - name: 'debugDumpRenderTree', + name: RenderingServiceExtensions.debugDumpRenderTree.name, callback: (Map parameters) async { final String data = RendererBinding.instance.renderView.toStringDeep(); return { @@ -164,7 +165,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerServiceExtension( - name: 'debugDumpSemanticsTreeInTraversalOrder', + name: RenderingServiceExtensions.debugDumpSemanticsTreeInTraversalOrder.name, callback: (Map parameters) async { return { 'data': _generateSemanticsTree(DebugSemanticsDumpOrder.traversalOrder), @@ -172,7 +173,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerServiceExtension( - name: 'debugDumpSemanticsTreeInInverseHitTestOrder', + name: RenderingServiceExtensions.debugDumpSemanticsTreeInInverseHitTestOrder.name, callback: (Map parameters) async { return { 'data': _generateSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest), @@ -180,7 +181,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'profileRenderObjectPaints', + name: RenderingServiceExtensions.profileRenderObjectPaints.name, getter: () async => debugProfilePaintsEnabled, setter: (bool value) async { if (debugProfilePaintsEnabled != value) { @@ -189,7 +190,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture }, ); registerBoolServiceExtension( - name: 'profileRenderObjectLayouts', + name: RenderingServiceExtensions.profileRenderObjectLayouts.name, getter: () async => debugProfileLayoutsEnabled, setter: (bool value) async { if (debugProfileLayoutsEnabled != value) { diff --git a/packages/flutter/lib/src/rendering/debug.dart b/packages/flutter/lib/src/rendering/debug.dart index 88f1cd4875a31..2879bac5a6aba 100644 --- a/packages/flutter/lib/src/rendering/debug.dart +++ b/packages/flutter/lib/src/rendering/debug.dart @@ -94,7 +94,7 @@ bool debugPrintLayouts = false; /// this on in your unit tests for additional validations. bool debugCheckIntrinsicSizes = false; -/// Adds [dart:developer.Timeline] events for every [RenderObject] layout. +/// Adds [Timeline] events for every [RenderObject] layout. /// /// The timing information this flag exposes is not representative of the actual /// cost of layout, because the overhead of adding timeline events is @@ -120,7 +120,7 @@ bool debugCheckIntrinsicSizes = false; /// debugging information related to [RenderObject] layouts. bool debugProfileLayoutsEnabled = false; -/// Adds [dart:developer.Timeline] events for every [RenderObject] painted. +/// Adds [Timeline] events for every [RenderObject] painted. /// /// The timing information this flag exposes is not representative of actual /// paints, because the overhead of adding timeline events is significant diff --git a/packages/flutter/lib/src/rendering/service_extensions.dart b/packages/flutter/lib/src/rendering/service_extensions.dart new file mode 100644 index 0000000000000..99d6da35097a0 --- /dev/null +++ b/packages/flutter/lib/src/rendering/service_extensions.dart @@ -0,0 +1,153 @@ +// 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. + +/// Service extension constants for the rendering library. +/// +/// These constants will be used when registering service extensions in the +/// framework, and they will also be used by tools and services that call these +/// service extensions. +/// +/// The String value for each of these extension names should be accessed by +/// calling the `.name` property on the enum value. +enum RenderingServiceExtensions { + /// Name of service extension that, when called, will toggle whether the + /// framework will color invert and horizontally flip images that have been + /// decoded to a size taking at least [debugImageOverheadAllowance] bytes more + /// than necessary. + /// + /// See also: + /// + /// * [debugInvertOversizedImages], which is the flag that this service + /// extension exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + invertOversizedImages, + + /// Name of service extension that, when called, will toggle whether each + /// [RenderBox] will paint a box around its bounds as well as additional boxes + /// showing construction lines. + /// + /// See also: + /// + /// * [debugPaintSizeEnabled], which is the flag that this service extension + /// exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugPaint, + + /// Name of service extension that, when called, will toggle whether each + /// [RenderBox] will paint a line at each of its baselines. + /// + /// See also: + /// + /// * [debugPaintBaselinesEnabled], which is the flag that this service + /// extension exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugPaintBaselinesEnabled, + + /// Name of service extension that, when called, will toggle whether a rotating + /// set of colors will be overlaid on the device when repainting layers in debug + /// mode. + /// + /// See also: + /// + /// * [debugRepaintRainbowEnabled], which is the flag that this service + /// extension exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + repaintRainbow, + + /// Name of service extension that, when called, will dump a [String] + /// representation of the layer tree to console. + /// + /// See also: + /// + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDumpLayerTree, + + + /// Name of service extension that, when called, will toggle whether all + /// clipping effects from the layer tree will be ignored. + /// + /// See also: + /// + /// * [debugDisableClipLayers], which is the flag that this service extension + /// exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDisableClipLayers, + + /// Name of service extension that, when called, will toggle whether all + /// physical modeling effects from the layer tree will be ignored. + /// + /// See also: + /// + /// * [debugDisablePhysicalShapeLayers], which is the flag that this service + /// extension exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDisablePhysicalShapeLayers, + + /// Name of service extension that, when called, will toggle whether all opacity + /// effects from the layer tree will be ignored. + /// + /// See also: + /// + /// * [debugDisableOpacityLayers], which is the flag that this service extension + /// exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDisableOpacityLayers, + + /// Name of service extension that, when called, will dump a [String] + /// representation of the render tree to console. + /// + /// See also: + /// + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDumpRenderTree, + + /// Name of service extension that, when called, will dump a [String] + /// representation of the semantics tree (in traversal order) to console. + /// + /// See also: + /// + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDumpSemanticsTreeInTraversalOrder, + + /// Name of service extension that, when called, will dump a [String] + /// representation of the semantics tree (in inverse hit test order) to console. + /// + /// See also: + /// + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + debugDumpSemanticsTreeInInverseHitTestOrder, + + /// Name of service extension that, when called, will toggle whether [Timeline] + /// events are added for every [RenderObject] painted. + /// + /// See also: + /// + /// * [debugProfilePaintsEnabled], which is the flag that this service extension + /// exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + profileRenderObjectPaints, + + /// Name of service extension that, when called, will toggle whether [Timeline] + /// events are added for every [RenderObject] laid out. + /// + /// See also: + /// + /// * [debugProfileLayoutsEnabled], which is the flag that this service + /// extension exposes. + /// * [RendererBinding.initServiceExtensions], where the service extension is + /// registered. + profileRenderObjectLayouts, +} diff --git a/packages/flutter/lib/src/services/hardware_keyboard.dart b/packages/flutter/lib/src/services/hardware_keyboard.dart index 224b12074dc37..025b198165ea7 100644 --- a/packages/flutter/lib/src/services/hardware_keyboard.dart +++ b/packages/flutter/lib/src/services/hardware_keyboard.dart @@ -146,7 +146,7 @@ abstract class KeyEvent with Diagnosticable { /// keystroke, if any. /// /// This will only return a character if this keystroke, combined with any - /// preceding keystroke(s), generats a character, and only on a "key down" + /// preceding keystroke(s), generates a character, and only on a "key down" /// event. It will return null if no character has been generated by the /// keystroke (e.g. a "dead" or "combining" key), or if the corresponding key /// is a key without a visual representation, such as a modifier key or a @@ -178,7 +178,7 @@ abstract class KeyEvent with Diagnosticable { /// might be converted to a Flutter down event when necessary.) /// /// A [synthesized] event is created without a source native event in order to - /// synthronize key states. For example, if the native platform shows that a + /// synchronize key states. For example, if the native platform shows that a /// shift key that was previously held has been released somehow without the /// key up event dispatched (probably due to loss of focus), a synthesized key /// up event will be added to regularized the event stream. @@ -790,7 +790,7 @@ class KeyEventManager { /// and calls the original callback in between (or not at all.) /// /// Patching [keyMessageHandler] can not be reverted. You should always assume - /// that another component might haved patched it before you and after you. + /// that another component might have patched it before you and after you. /// This means that you might want to write your own global notification /// manager, to which callbacks can be added and removed. /// @@ -804,7 +804,7 @@ class KeyEventManager { /// /// The app prints out any key events that are not handled by the app body. /// Try typing something in the first text field. These key presses are not - /// handled by `Shorcuts` and will be sent to the fallback handler and printed + /// handled by `Shortcuts` and will be sent to the fallback handler and printed /// out. Now try some text shortcuts, such as Ctrl+A. The KeyA press is /// handled as a shortcut, and is not sent to the fallback handler and so is /// not printed out. diff --git a/packages/flutter/lib/src/services/platform_channel.dart b/packages/flutter/lib/src/services/platform_channel.dart index 47b609b3de821..66f1e7e8e8830 100644 --- a/packages/flutter/lib/src/services/platform_channel.dart +++ b/packages/flutter/lib/src/services/platform_channel.dart @@ -268,10 +268,10 @@ class MethodChannel { /// [binaryMessenger]'s [BinaryMessenger.send] method. /// /// If the result is null and `missingOk` is true, this returns null. (This is - /// the behaviour of [OptionalMethodChannel.invokeMethod].) + /// the behavior of [OptionalMethodChannel.invokeMethod].) /// /// If the result is null and `missingOk` is false, this throws a - /// [MissingPluginException]. (This is the behaviour of + /// [MissingPluginException]. (This is the behavior of /// [MethodChannel.invokeMethod].) /// /// Otherwise, the result is decoded using the [codec]'s diff --git a/packages/flutter/lib/src/services/spell_check.dart b/packages/flutter/lib/src/services/spell_check.dart index 785d967cbde73..c8ff5d03204a6 100644 --- a/packages/flutter/lib/src/services/spell_check.dart +++ b/packages/flutter/lib/src/services/spell_check.dart @@ -108,10 +108,10 @@ abstract class SpellCheckService { /// See also: /// /// * [SpellCheckService], the service that this implements that may be -/// overriden for use by [EditableText]. +/// overridden for use by [EditableText]. /// * [EditableText], which may use this service to fetch results. class DefaultSpellCheckService implements SpellCheckService { - /// Creates service to spell check text input by default via communcication + /// Creates service to spell check text input by default via communication /// over the spell check [MethodChannel]. DefaultSpellCheckService() { spellCheckChannel = SystemChannels.spellCheck; diff --git a/packages/flutter/lib/src/services/system_channels.dart b/packages/flutter/lib/src/services/system_channels.dart index 8d5851c58fbec..d8b661166fe32 100644 --- a/packages/flutter/lib/src/services/system_channels.dart +++ b/packages/flutter/lib/src/services/system_channels.dart @@ -227,7 +227,7 @@ class SystemChannels { /// This channel exposes the spell check framework for supported platforms. /// Currently supported on Android only. /// - /// Spell check requests are intiated by `SpellCheck.initiateSpellCheck`. + /// Spell check requests are initiated by `SpellCheck.initiateSpellCheck`. /// These requests may either be completed or canceled. If the request is /// completed, the shell side will respond with the results of the request. /// Otherwise, the shell side will respond with null. @@ -238,7 +238,7 @@ class SystemChannels { /// * `SpellCheck.initiateSpellCheck`: Sends request for specified text to be /// spell checked and returns the result, either a [List] /// representing the spell check results of the text or null if the request - /// was cancelled. The arguments are the [String] to be spell checked + /// was canceled. The arguments are the [String] to be spell checked /// and the [Locale] for the text to be spell checked with. static const MethodChannel spellCheck = OptionalMethodChannel( 'flutter/spellcheck', diff --git a/packages/flutter/lib/src/services/text_editing_delta.dart b/packages/flutter/lib/src/services/text_editing_delta.dart index aeded5e09fb42..f4415bb335c00 100644 --- a/packages/flutter/lib/src/services/text_editing_delta.dart +++ b/packages/flutter/lib/src/services/text_editing_delta.dart @@ -247,7 +247,7 @@ abstract class TextEditingDelta { TextEditingValue apply(TextEditingValue value); } -/// A structure representing an insertion of a single/or contigous sequence of +/// A structure representing an insertion of a single/or contiguous sequence of /// characters at some offset of an editing state. @immutable class TextEditingDeltaInsertion extends TextEditingDelta { diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart index 937d97dffd479..180ef4bf270e9 100644 --- a/packages/flutter/lib/src/services/text_input.dart +++ b/packages/flutter/lib/src/services/text_input.dart @@ -827,11 +827,11 @@ class TextEditingValue { /// prediction changes. /// /// Composing regions can also be used for performing multistage input, which - /// is typically used by IMEs designed for phoetic keyboard to enter + /// is typically used by IMEs designed for phonetic keyboard to enter /// ideographic symbols. As an example, many CJK keyboards require the user to - /// enter a latin alphabet sequence and then convert it to CJK characters. On + /// enter a Latin alphabet sequence and then convert it to CJK characters. On /// iOS, the default software keyboards do not have a dedicated view to show - /// the unfinished latin sequence, so it's displayed directly in the text + /// the unfinished Latin sequence, so it's displayed directly in the text /// field, inside of a composing region. /// /// The composing region should typically only be changed by the IME, or the @@ -879,7 +879,7 @@ class TextEditingValue { /// /// This method also adjusts the selection range and the composing range of the /// resulting [TextEditingValue], such that they point to the same substrings - /// as the correspoinding ranges in the original [TextEditingValue]. For + /// as the corresponding ranges in the original [TextEditingValue]. For /// example, if the original [TextEditingValue] is "Hello world" with the word /// "world" selected, replacing "Hello" with a different string using this /// method will not change the selected word. diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart index c64fdc410e498..bc0f6daef6b29 100644 --- a/packages/flutter/lib/src/widgets/binding.dart +++ b/packages/flutter/lib/src/widgets/binding.dart @@ -18,6 +18,7 @@ import 'focus_manager.dart'; import 'framework.dart'; import 'platform_menu_bar.dart'; import 'router.dart'; +import 'service_extensions.dart'; import 'widget_inspector.dart'; export 'dart:ui' show AppLifecycleState, Locale; @@ -360,7 +361,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB if (!kReleaseMode) { registerServiceExtension( - name: 'debugDumpApp', + name: WidgetsServiceExtensions.debugDumpApp.name, callback: (Map parameters) async { final String data = _debugDumpAppString(); return { @@ -371,7 +372,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB if (!kIsWeb) { registerBoolServiceExtension( - name: 'showPerformanceOverlay', + name: WidgetsServiceExtensions.showPerformanceOverlay.name, getter: () => Future.value(WidgetsApp.showPerformanceOverlayOverride), setter: (bool value) { @@ -385,7 +386,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB } registerServiceExtension( - name: 'didSendFirstFrameEvent', + name: WidgetsServiceExtensions.didSendFirstFrameEvent.name, callback: (_) async { return { // This is defined to return a STRING, not a boolean. @@ -396,10 +397,8 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB }, ); - // This returns 'true' when the first frame is rasterized, and the trace - // event 'Rasterized first useful frame' is sent out. registerServiceExtension( - name: 'didSendFirstFrameRasterizedEvent', + name: WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, callback: (_) async { return { // This is defined to return a STRING, not a boolean. @@ -411,7 +410,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ); registerServiceExtension( - name: 'fastReassemble', + name: WidgetsServiceExtensions.fastReassemble.name, callback: (Map params) async { // This mirrors the implementation of the 'reassemble' callback registration // in lib/src/foundation/binding.dart, but with the extra binding config used @@ -429,7 +428,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB // Expose the ability to send Widget rebuilds as [Timeline] events. registerBoolServiceExtension( - name: 'profileWidgetBuilds', + name: WidgetsServiceExtensions.profileWidgetBuilds.name, getter: () async => debugProfileBuildsEnabled, setter: (bool value) async { if (debugProfileBuildsEnabled != value) { @@ -438,7 +437,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB }, ); registerBoolServiceExtension( - name: 'profileUserWidgetBuilds', + name: WidgetsServiceExtensions.profileUserWidgetBuilds.name, getter: () async => debugProfileBuildsEnabledUserWidgets, setter: (bool value) async { if (debugProfileBuildsEnabledUserWidgets != value) { @@ -450,7 +449,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB assert(() { registerBoolServiceExtension( - name: 'debugAllowBanner', + name: WidgetsServiceExtensions.debugAllowBanner.name, getter: () => Future.value(WidgetsApp.debugAllowBannerOverride), setter: (bool value) { if (WidgetsApp.debugAllowBannerOverride == value) { @@ -461,20 +460,6 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB }, ); - // This service extension is deprecated and will be removed by 12/1/2018. - // Use ext.flutter.inspector.show instead. - registerBoolServiceExtension( - name: 'debugWidgetInspector', - getter: () async => WidgetsApp.debugShowWidgetInspectorOverride, - setter: (bool value) { - if (WidgetsApp.debugShowWidgetInspectorOverride == value) { - return Future.value(); - } - WidgetsApp.debugShowWidgetInspectorOverride = value; - return _forceRebuild(); - }, - ); - WidgetInspectorService.instance.initServiceExtensions(registerServiceExtension); return true; diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index 8fa7f9fca9a7e..91524177ceec3 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -4189,7 +4189,7 @@ class _ScribblePlaceholder extends WidgetSpan { } } -/// An interface for retriving the logical text boundary (left-closed-right-open) +/// An interface for retrieving the logical text boundary (left-closed-right-open) /// at a given location in a document. /// /// Depending on the implementation of the [_TextBoundary], the input diff --git a/packages/flutter/lib/src/widgets/fade_in_image.dart b/packages/flutter/lib/src/widgets/fade_in_image.dart index e169bc9a0b4e3..73f64fc6e3a06 100644 --- a/packages/flutter/lib/src/widgets/fade_in_image.dart +++ b/packages/flutter/lib/src/widgets/fade_in_image.dart @@ -562,7 +562,8 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate @override Widget build(BuildContext context) { - if (widget.wasSynchronouslyLoaded || _placeholderOpacityAnimation!.isCompleted) { + if (widget.wasSynchronouslyLoaded || + (_placeholderOpacityAnimation?.isCompleted ?? true)) { return widget.target; } diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index bc801ae777b0f..d083391f49bc1 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -459,7 +459,7 @@ abstract class Widget extends DiagnosticableTree { /// Flutter would short-circuit most of the rebuild work. /// {@endtemplate} /// -/// This video gives more explainations on why `const` constructors are important +/// This video gives more explanations on why `const` constructors are important /// and why a [Widget] is better than a helper method. /// /// {@youtube 560 315 https://www.youtube.com/watch?v=IOyq-eTRhvo} @@ -657,7 +657,7 @@ abstract class StatelessWidget extends Widget { /// subtree and re-use it each time it can be used. To do this, simply assign /// a widget to a `final` state variable and re-use it in the build method. It /// is massively more efficient for a widget to be re-used than for a new (but -/// identically-configured) widget to be created. Another caching stragegy +/// identically-configured) widget to be created. Another caching strategy /// consists in extracting the mutable part of the widget into a [StatefulWidget] /// which accepts a child parameter. /// @@ -682,7 +682,7 @@ abstract class StatelessWidget extends Widget { /// /// {@macro flutter.flutter.widgets.framework.prefer_const_over_helper} /// -/// This video gives more explainations on why `const` constructors are important +/// This video gives more explanations on why `const` constructors are important /// and why a [Widget] is better than a helper method. /// /// {@youtube 560 315 https://www.youtube.com/watch?v=IOyq-eTRhvo} @@ -855,7 +855,7 @@ typedef StateSetter = void Function(VoidCallback fn); /// * At this point, the [State] object is fully initialized and the framework /// might call its [build] method any number of times to obtain a /// description of the user interface for this subtree. [State] objects can -/// spontaneously request to rebuild their subtree by callings their +/// spontaneously request to rebuild their subtree by calling their /// [setState] method, which indicates that some of their internal state /// has changed in a way that might impact the user interface in this /// subtree. @@ -3263,7 +3263,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { /// /// Avoid overriding this field on [Element] subtypes to provide a more /// specific widget type (i.e. [StatelessElement] and [StatelessWidget]). - /// Instead, cast at any callsites where the more specific type is required. + /// Instead, cast at any call sites where the more specific type is required. /// This avoids significant cast overhead on the getter which is accessed /// throughout the framework internals during the build phase - and for which /// the more specific type information is not used. @@ -4585,7 +4585,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { /// called to mark this element dirty, by [mount] when the element is first /// built, and by [update] when the widget has changed. /// - /// The method will only rebuild if [dirty] is true. To rebuild irregardless + /// The method will only rebuild if [dirty] is true. To rebuild regardless /// of the [dirty] flag, set `force` to true. Forcing a rebuild is convenient /// from [update], during which [dirty] is false. @pragma('vm:prefer-inline') @@ -5518,7 +5518,7 @@ class InheritedElement extends ProxyElement { /// [RenderObjectElement] objects spend much of their time acting as /// intermediaries between their [widget] and their [renderObject]. It is /// generally recommended against specializing the [widget] getter and -/// instead casting at the various callsites to avoid adding overhead +/// instead casting at the various call sites to avoid adding overhead /// outside of this particular implementation. /// /// ```dart @@ -5800,7 +5800,7 @@ abstract class RenderObjectElement extends Element { /// and then returns the new child list. /// /// During this function the `oldChildren` list must not be modified. If the - /// caller wishes to remove elements from `oldChildren` re-entrantly while + /// caller wishes to remove elements from `oldChildren` reentrantly while /// this function is on the stack, the caller can supply a `forgottenChildren` /// argument, which can be modified while this function is on the stack. /// Whenever this function reads from `oldChildren`, this function first diff --git a/packages/flutter/lib/src/widgets/image_filter.dart b/packages/flutter/lib/src/widgets/image_filter.dart index 67f9ae459fecc..09648211e338d 100644 --- a/packages/flutter/lib/src/widgets/image_filter.dart +++ b/packages/flutter/lib/src/widgets/image_filter.dart @@ -46,7 +46,7 @@ class ImageFiltered extends SingleChildRenderObjectWidget { /// The image filter to apply to the child of this widget. final ImageFilter imageFilter; - /// Whether or not to apply the image filter opation to the child of this + /// Whether or not to apply the image filter operation to the child of this /// widget. /// /// Prefer setting enabled to `false` instead of creating a "no-op" filter diff --git a/packages/flutter/lib/src/widgets/reorderable_list.dart b/packages/flutter/lib/src/widgets/reorderable_list.dart index 4c0cee78c26e4..9158013aa84a5 100644 --- a/packages/flutter/lib/src/widgets/reorderable_list.dart +++ b/packages/flutter/lib/src/widgets/reorderable_list.dart @@ -344,7 +344,7 @@ class ReorderableListState extends State { /// the pointer down [event]. /// /// The given [recognizer] will be used to recognize and start the drag - /// item tracking and lead to either an item reorder, or a cancelled drag. + /// item tracking and lead to either an item reorder, or a canceled drag. /// The list will take ownership of the returned recognizer and will dispose /// it when it is no longer needed. /// @@ -637,7 +637,7 @@ class SliverReorderableListState extends State with Ticke /// the pointer down [event]. /// /// The given [recognizer] will be used to recognize and start the drag - /// item tracking and lead to either an item reorder, or a cancelled drag. + /// item tracking and lead to either an item reorder, or a canceled drag. /// /// Most applications will not use this directly, but will wrap the item /// (or part of the item, like a drag handle) in either a diff --git a/packages/flutter/lib/src/widgets/router.dart b/packages/flutter/lib/src/widgets/router.dart index 69a0576e9ddb2..27428948a96b6 100644 --- a/packages/flutter/lib/src/widgets/router.dart +++ b/packages/flutter/lib/src/widgets/router.dart @@ -818,7 +818,7 @@ class _RouterScope extends InheritedWidget { /// See also: /// /// * [Listenable] and its subclasses, which provide a similar mechanism for -/// one-way signalling. +/// one-way signaling. class _CallbackHookProvider { final ObserverList> _callbacks = ObserverList>(); @@ -1203,7 +1203,7 @@ abstract class RouteInformationParser { /// /// The input [BuildContext] can be used for looking up [InheritedWidget]s /// If one uses [BuildContext.dependOnInheritedWidgetOfExactType], a - /// dependency will be created. The [Router] will reparse the + /// dependency will be created. The [Router] will re-parse the /// [RouteInformation] from its [RouteInformationProvider] if the dependency /// notifies its listeners. /// diff --git a/packages/flutter/lib/src/widgets/scrollbar.dart b/packages/flutter/lib/src/widgets/scrollbar.dart index f157e9f693366..0297421ee45aa 100644 --- a/packages/flutter/lib/src/widgets/scrollbar.dart +++ b/packages/flutter/lib/src/widgets/scrollbar.dart @@ -934,7 +934,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter { /// /// {@tool dartpad} /// This sample shows how to disable the default Scrollbar for a [Scrollable] -/// widget to avoid duplicate Scrollbars when runnung on desktop platforms. +/// widget to avoid duplicate Scrollbars when running on desktop platforms. /// /// ** See code in examples/api/lib/widgets/scrollbar/raw_scrollbar.desktop.0.dart ** /// {@end-tool} diff --git a/packages/flutter/lib/src/widgets/service_extensions.dart b/packages/flutter/lib/src/widgets/service_extensions.dart new file mode 100644 index 0000000000000..49c80f94fddde --- /dev/null +++ b/packages/flutter/lib/src/widgets/service_extensions.dart @@ -0,0 +1,96 @@ +// 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. + +/// Service extension constants for the widgets library. +/// +/// These constants will be used when registering service extensions in the +/// framework, and they will also be used by tools and services that call these +/// service extensions. +/// +/// The String value for each of these extension names should be accessed by +/// calling the `.name` property on the enum value. +enum WidgetsServiceExtensions { + /// Name of service extension that, when called, will output a string + /// representation of this app's widget tree to console. + /// + /// See also: + /// + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + debugDumpApp, + + /// Name of service extension that, when called, will overlay a performance + /// graph on top of this app. + /// + /// See also: + /// + /// * [WidgetsApp.showPerformanceOverlayOverride], which is the flag + /// that this service extension exposes. + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + showPerformanceOverlay, + + /// Name of service extension that, when called, will return whether the first + /// 'Flutter.Frame' event has been reported on the Extension stream. + /// + /// See also: + /// + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + didSendFirstFrameEvent, + + /// Name of service extension that, when called, will return whether the first + /// frame has been rasterized and the trace event 'Rasterized first useful + /// frame' has been sent out. + /// + /// See also: + /// + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + didSendFirstFrameRasterizedEvent, + + /// Name of service extension that, when called, will reassemble the + /// application. + /// + /// See also: + /// + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + fastReassemble, + + /// Name of service extension that, when called, will change the value of + /// [debugProfileBuildsEnabled], which adds [Timeline] events for every widget + /// built. + /// + /// See also: + /// + /// * [debugProfileBuildsEnabled], which is the flag that this service extension + /// exposes. + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + profileWidgetBuilds, + + /// Name of service extension that, when called, will change the value of + /// [debugProfileBuildsEnabledUserWidgets], which adds [Timeline] events for + /// every user-created widget built. + /// + /// See also: + /// * [debugProfileBuildsEnabledUserWidgets], which is the flag that this + /// service extension exposes. + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + profileUserWidgetBuilds, + + /// Name of service extension that, when called, will change the value of + /// [WidgetsApp.debugAllowBannerOverride], which controls the visibility of the + /// debug banner for debug mode apps. + /// + /// See also: + /// + /// * [WidgetsApp.debugAllowBannerOverride], which is the flag that this service + /// extension exposes. + /// * [WidgetsBinding.initServiceExtensions], where the service extension is + /// registered. + debugAllowBanner, +} diff --git a/packages/flutter/lib/src/widgets/snapshot_widget.dart b/packages/flutter/lib/src/widgets/snapshot_widget.dart index 9ce0e73bd54b8..9583cdc4f5ac7 100644 --- a/packages/flutter/lib/src/widgets/snapshot_widget.dart +++ b/packages/flutter/lib/src/widgets/snapshot_widget.dart @@ -70,7 +70,7 @@ class SnapshotController extends ChangeNotifier { } } -/// A widget that can replace its child with a snapshoted version of the child. +/// A widget that can replace its child with a snapshotted version of the child. /// /// A snapshot is a frozen texture-backed representation of all child pictures /// and layers stored as a [ui.Image]. diff --git a/packages/flutter/lib/src/widgets/tap_region.dart b/packages/flutter/lib/src/widgets/tap_region.dart index 661c7144b4da3..3fd49021f2c05 100644 --- a/packages/flutter/lib/src/widgets/tap_region.dart +++ b/packages/flutter/lib/src/widgets/tap_region.dart @@ -93,7 +93,7 @@ abstract class TapRegionRegistry { /// encompass the entire area where taps should be monitored. This is typically /// around the entire app. If the entire app isn't covered, then taps outside of /// the `TapRegionSurface` will be ignored and no [TapRegion.onTapOutside] calls -/// wil be made for those events. The [WidgetsApp], [MaterialApp] and +/// will be made for those events. The [WidgetsApp], [MaterialApp] and /// [CupertinoApp] automatically include a `TapRegionSurface` around their /// entire app. /// @@ -155,7 +155,7 @@ class TapRegionSurface extends SingleChildRenderObjectWidget { /// to encompass the entire area where taps should be monitored. This is /// typically around the entire app. If the entire app isn't covered, then taps /// outside of the `RenderTapRegionSurface` will be ignored and no -/// [RenderTapRegion.onTapOutside] calls wil be made for those events. The +/// [RenderTapRegion.onTapOutside] calls will be made for those events. The /// [WidgetsApp], [MaterialApp] and [CupertinoApp] automatically include a /// `RenderTapRegionSurface` around the entire app. /// diff --git a/packages/flutter/lib/src/widgets/text_editing_intents.dart b/packages/flutter/lib/src/widgets/text_editing_intents.dart index 493e6fb711430..7ae97387575ef 100644 --- a/packages/flutter/lib/src/widgets/text_editing_intents.dart +++ b/packages/flutter/lib/src/widgets/text_editing_intents.dart @@ -28,7 +28,7 @@ abstract class DirectionalTextEditingIntent extends Intent { /// operation from the current caret location towards the end of the document. /// /// Unless otherwise specified by the recipient of this intent, this parameter - /// uses the logical order of characters in the string to determind the + /// uses the logical order of characters in the string to determine the /// direction, and is not affected by the writing direction of the text. final bool forward; } diff --git a/packages/flutter/lib/src/widgets/text_selection.dart b/packages/flutter/lib/src/widgets/text_selection.dart index 00fc689e94155..3c7d3b972a34f 100644 --- a/packages/flutter/lib/src/widgets/text_selection.dart +++ b/packages/flutter/lib/src/widgets/text_selection.dart @@ -2592,6 +2592,6 @@ enum ClipboardStatus { /// waiting to receive the clipboard contents for the first time. unknown, - /// The content on the clipboard is not pasteable, such as when it is empty. + /// The content on the clipboard is not pastable, such as when it is empty. notPasteable, } diff --git a/packages/flutter/lib/src/widgets/ticker_provider.dart b/packages/flutter/lib/src/widgets/ticker_provider.dart index 56202ba8c2efd..d5e006cf02618 100644 --- a/packages/flutter/lib/src/widgets/ticker_provider.dart +++ b/packages/flutter/lib/src/widgets/ticker_provider.dart @@ -75,7 +75,7 @@ class TickerMode extends StatefulWidget { /// the `context` and the [TickerMode] and the widget owning the `context` /// does not rebuild when the ticker mode changes from true to false or vice /// versa. This is preferable when the ticker mode does not impact what is - /// currently rendered on screen, e.g. because it is ony used to mute/unmute a + /// currently rendered on screen, e.g. because it is only used to mute/unmute a /// [Ticker]. Since no dependency is established, the widget owning the /// `context` is also not informed when it is moved to a new location in the /// tree where it may have a different [TickerMode] ancestor. When this diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index cbbfa8f5d4746..29a7771c4f082 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -1531,7 +1531,7 @@ mixin WidgetInspectorService { } /// Returns JSON representing the chain of [DiagnosticsNode] instances from - /// root of thee tree to the [Element] or [RenderObject] matching `id`. + /// root of the tree to the [Element] or [RenderObject] matching `id`. /// /// The JSON contains all information required to display a tree view with /// all nodes other than nodes along the path collapsed. diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart index 0719ad33d912b..e36197735b958 100644 --- a/packages/flutter/lib/widgets.dart +++ b/packages/flutter/lib/widgets.dart @@ -116,6 +116,7 @@ export 'src/widgets/scrollbar.dart'; export 'src/widgets/selectable_region.dart'; export 'src/widgets/selection_container.dart'; export 'src/widgets/semantics_debugger.dart'; +export 'src/widgets/service_extensions.dart'; export 'src/widgets/shared_app_data.dart'; export 'src/widgets/shortcuts.dart'; export 'src/widgets/single_child_scroll_view.dart'; diff --git a/packages/flutter/test/cupertino/date_picker_test.dart b/packages/flutter/test/cupertino/date_picker_test.dart index 5e0326b1cd171..2df4f4941a83a 100644 --- a/packages/flutter/test/cupertino/date_picker_test.dart +++ b/packages/flutter/test/cupertino/date_picker_test.dart @@ -19,6 +19,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +// TODO(yjbanov): on the web text rendered with perspective produces flaky goldens: https://github.com/flutter/flutter/issues/110785 +const bool skipPerspectiveTextGoldens = isBrowser; + // A number of the hit tests below say "warnIfMissed: false". This is because // the way the CupertinoPicker works, the hits don't actually reach the labels, // the scroll view intercepts them. @@ -1194,31 +1197,39 @@ void main() { } await tester.pumpWidget(buildApp(CupertinoDatePickerMode.time)); - await expectLater( - find.byType(CupertinoDatePicker), - matchesGoldenFile('date_picker_test.time.initial.png'), - ); + if (!skipPerspectiveTextGoldens) { + await expectLater( + find.byType(CupertinoDatePicker), + matchesGoldenFile('date_picker_test.time.initial.png'), + ); + } await tester.pumpWidget(buildApp(CupertinoDatePickerMode.date)); - await expectLater( - find.byType(CupertinoDatePicker), - matchesGoldenFile('date_picker_test.date.initial.png'), - ); + if (!skipPerspectiveTextGoldens) { + await expectLater( + find.byType(CupertinoDatePicker), + matchesGoldenFile('date_picker_test.date.initial.png'), + ); + } await tester.pumpWidget(buildApp(CupertinoDatePickerMode.dateAndTime)); - await expectLater( - find.byType(CupertinoDatePicker), - matchesGoldenFile('date_picker_test.datetime.initial.png'), - ); + if (!skipPerspectiveTextGoldens) { + await expectLater( + find.byType(CupertinoDatePicker), + matchesGoldenFile('date_picker_test.datetime.initial.png'), + ); + } // Slightly drag the hour component to make the current hour off-center. await tester.drag(find.text('4'), Offset(0, _kRowOffset.dy / 2), warnIfMissed: false); // see top of file await tester.pump(); - await expectLater( - find.byType(CupertinoDatePicker), - matchesGoldenFile('date_picker_test.datetime.drag.png'), - ); + if (!skipPerspectiveTextGoldens) { + await expectLater( + find.byType(CupertinoDatePicker), + matchesGoldenFile('date_picker_test.datetime.drag.png'), + ); + } }); testWidgets('DatePicker displays the date in correct order', (WidgetTester tester) async { diff --git a/packages/flutter/test/foundation/service_extensions_test.dart b/packages/flutter/test/foundation/service_extensions_test.dart index 827c60edcc360..2ba427bcb902c 100644 --- a/packages/flutter/test/foundation/service_extensions_test.dart +++ b/packages/flutter/test/foundation/service_extensions_test.dart @@ -132,21 +132,21 @@ void main() { // after the first binding.doFrame() call. Map firstFrameResult; expect(binding.debugDidSendFirstFrameEvent, isFalse); - firstFrameResult = await binding.testExtension('didSendFirstFrameEvent', {}); + firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, {}); expect(firstFrameResult, {'enabled': 'false'}); expect(binding.firstFrameRasterized, isFalse); - firstFrameResult = await binding.testExtension('didSendFirstFrameRasterizedEvent', {}); + firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, {}); expect(firstFrameResult, {'enabled': 'false'}); await binding.doFrame(); expect(binding.debugDidSendFirstFrameEvent, isTrue); - firstFrameResult = await binding.testExtension('didSendFirstFrameEvent', {}); + firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameEvent.name, {}); expect(firstFrameResult, {'enabled': 'true'}); expect(binding.firstFrameRasterized, isTrue); - firstFrameResult = await binding.testExtension('didSendFirstFrameRasterizedEvent', {}); + firstFrameResult = await binding.testExtension(WidgetsServiceExtensions.didSendFirstFrameRasterizedEvent.name, {}); expect(firstFrameResult, {'enabled': 'true'}); expect(binding.frameScheduled, isFalse); @@ -176,7 +176,7 @@ void main() { // framework, excluding any that are for the widget inspector // (see widget_inspector_test.dart for tests of the ext.flutter.inspector // service extensions). - const int serviceExtensionCount = 38; + const int serviceExtensionCount = 37; expect(binding.extensions.length, serviceExtensionCount + widgetInspectorExtensionCount - disabledExtensions); @@ -191,26 +191,26 @@ void main() { expect(binding.frameScheduled, isFalse); expect(WidgetsApp.debugAllowBannerOverride, true); - result = await binding.testExtension('debugAllowBanner', {}); + result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, {}); expect(result, {'enabled': 'true'}); expect(WidgetsApp.debugAllowBannerOverride, true); - result = await binding.testExtension('debugAllowBanner', {'enabled': 'false'}); + result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(WidgetsApp.debugAllowBannerOverride, false); - result = await binding.testExtension('debugAllowBanner', {}); + result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, {}); expect(result, {'enabled': 'false'}); expect(WidgetsApp.debugAllowBannerOverride, false); - result = await binding.testExtension('debugAllowBanner', {'enabled': 'true'}); + result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(WidgetsApp.debugAllowBannerOverride, true); - result = await binding.testExtension('debugAllowBanner', {}); + result = await binding.testExtension(WidgetsServiceExtensions.debugAllowBanner.name, {}); expect(result, {'enabled': 'true'}); expect(WidgetsApp.debugAllowBannerOverride, true); expect(binding.frameScheduled, isFalse); }); test('Service extensions - debugDumpApp', () async { - final Map result = await binding.testExtension('debugDumpApp', {}); + final Map result = await binding.testExtension(WidgetsServiceExtensions.debugDumpApp.name, {}); expect(result, { 'data': matches('TestServiceExtensionsBinding - DEBUG MODE\n'), @@ -219,7 +219,7 @@ void main() { test('Service extensions - debugDumpRenderTree', () async { await binding.doFrame(); - final Map result = await binding.testExtension('debugDumpRenderTree', {}); + final Map result = await binding.testExtension(RenderingServiceExtensions.debugDumpRenderTree.name, {}); expect(result, { 'data': matches( @@ -236,7 +236,7 @@ void main() { test('Service extensions - debugDumpLayerTree', () async { await binding.doFrame(); - final Map result = await binding.testExtension('debugDumpLayerTree', {}); + final Map result = await binding.testExtension(RenderingServiceExtensions.debugDumpLayerTree.name, {}); expect(result, { 'data': matches( @@ -259,7 +259,7 @@ void main() { test('Service extensions - debugDumpSemanticsTreeInTraversalOrder', () async { await binding.doFrame(); - final Map result = await binding.testExtension('debugDumpSemanticsTreeInTraversalOrder', {}); + final Map result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInTraversalOrder.name, {}); expect(result, { 'data': 'Semantics not generated.\n' @@ -271,7 +271,7 @@ void main() { test('Service extensions - debugDumpSemanticsTreeInInverseHitTestOrder', () async { await binding.doFrame(); - final Map result = await binding.testExtension('debugDumpSemanticsTreeInInverseHitTestOrder', {}); + final Map result = await binding.testExtension(RenderingServiceExtensions.debugDumpSemanticsTreeInInverseHitTestOrder.name, {}); expect(result, { 'data': 'Semantics not generated.\n' @@ -290,12 +290,12 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugPaintSizeEnabled, false); - result = await binding.testExtension('debugPaint', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, {}); expect(result, {'enabled': 'false'}); expect(debugPaintSizeEnabled, false); expect(extensionChangedEvents, isEmpty); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugPaint', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -312,12 +312,12 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint'); expect(extensionChangedEvent['value'], 'true'); - result = await binding.testExtension('debugPaint', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, {}); expect(result, {'enabled': 'true'}); expect(debugPaintSizeEnabled, true); expect(extensionChangedEvents.length, 1); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugPaint', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaint.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -329,7 +329,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.debugPaint'); expect(extensionChangedEvent['value'], 'false'); - result = await binding.testExtension('debugPaint', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaint.name, {}); expect(result, {'enabled': 'false'}); expect(debugPaintSizeEnabled, false); expect(extensionChangedEvents.length, 2); @@ -343,11 +343,11 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugPaintBaselinesEnabled, false); - result = await binding.testExtension('debugPaintBaselinesEnabled', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, {}); expect(result, {'enabled': 'false'}); expect(debugPaintBaselinesEnabled, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugPaintBaselinesEnabled', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -360,11 +360,11 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'true'}); expect(debugPaintBaselinesEnabled, true); - result = await binding.testExtension('debugPaintBaselinesEnabled', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, {}); expect(result, {'enabled': 'true'}); expect(debugPaintBaselinesEnabled, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugPaintBaselinesEnabled', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -372,7 +372,7 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'false'}); expect(debugPaintBaselinesEnabled, false); - result = await binding.testExtension('debugPaintBaselinesEnabled', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugPaintBaselinesEnabled.name, {}); expect(result, {'enabled': 'false'}); expect(debugPaintBaselinesEnabled, false); expect(binding.frameScheduled, isFalse); @@ -385,12 +385,12 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugInvertOversizedImages, false); - result = await binding.testExtension('invertOversizedImages', {}); + result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, {}); expect(result, {'enabled': 'false'}); expect(debugInvertOversizedImages, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('invertOversizedImages', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -404,12 +404,12 @@ void main() { expect(result, {'enabled': 'true'}); expect(debugInvertOversizedImages, true); - result = await binding.testExtension('invertOversizedImages', {}); + result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, {}); expect(result, {'enabled': 'true'}); expect(debugInvertOversizedImages, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('invertOversizedImages', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -418,7 +418,7 @@ void main() { expect(result, {'enabled': 'false'}); expect(debugInvertOversizedImages, false); - result = await binding.testExtension('invertOversizedImages', {}); + result = await binding.testExtension(RenderingServiceExtensions.invertOversizedImages.name, {}); expect(result, {'enabled': 'false'}); expect(debugInvertOversizedImages, false); expect(binding.frameScheduled, isFalse); @@ -430,23 +430,23 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugProfileBuildsEnabled, false); - result = await binding.testExtension('profileWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabled, false); - result = await binding.testExtension('profileWidgetBuilds', {'enabled': 'true'}); + result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(debugProfileBuildsEnabled, true); - result = await binding.testExtension('profileWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, {}); expect(result, {'enabled': 'true'}); expect(debugProfileBuildsEnabled, true); - result = await binding.testExtension('profileWidgetBuilds', {'enabled': 'false'}); + result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabled, false); - result = await binding.testExtension('profileWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileWidgetBuilds.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabled, false); @@ -459,23 +459,23 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugProfileBuildsEnabledUserWidgets, false); - result = await binding.testExtension('profileUserWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabledUserWidgets, false); - result = await binding.testExtension('profileUserWidgetBuilds', {'enabled': 'true'}); + result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(debugProfileBuildsEnabledUserWidgets, true); - result = await binding.testExtension('profileUserWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, {}); expect(result, {'enabled': 'true'}); expect(debugProfileBuildsEnabledUserWidgets, true); - result = await binding.testExtension('profileUserWidgetBuilds', {'enabled': 'false'}); + result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabledUserWidgets, false); - result = await binding.testExtension('profileUserWidgetBuilds', {}); + result = await binding.testExtension(WidgetsServiceExtensions.profileUserWidgetBuilds.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileBuildsEnabledUserWidgets, false); @@ -488,23 +488,23 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugProfileBuildsEnabled, false); - result = await binding.testExtension('profileRenderObjectPaints', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfilePaintsEnabled, false); - result = await binding.testExtension('profileRenderObjectPaints', {'enabled': 'true'}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(debugProfilePaintsEnabled, true); - result = await binding.testExtension('profileRenderObjectPaints', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, {}); expect(result, {'enabled': 'true'}); expect(debugProfilePaintsEnabled, true); - result = await binding.testExtension('profileRenderObjectPaints', {'enabled': 'false'}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(debugProfilePaintsEnabled, false); - result = await binding.testExtension('profileRenderObjectPaints', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectPaints.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfilePaintsEnabled, false); @@ -517,23 +517,23 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugProfileLayoutsEnabled, false); - result = await binding.testExtension('profileRenderObjectLayouts', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileLayoutsEnabled, false); - result = await binding.testExtension('profileRenderObjectLayouts', {'enabled': 'true'}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(debugProfileLayoutsEnabled, true); - result = await binding.testExtension('profileRenderObjectLayouts', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, {}); expect(result, {'enabled': 'true'}); expect(debugProfileLayoutsEnabled, true); - result = await binding.testExtension('profileRenderObjectLayouts', {'enabled': 'false'}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(debugProfileLayoutsEnabled, false); - result = await binding.testExtension('profileRenderObjectLayouts', {}); + result = await binding.testExtension(RenderingServiceExtensions.profileRenderObjectLayouts.name, {}); expect(result, {'enabled': 'false'}); expect(debugProfileLayoutsEnabled, false); @@ -578,7 +578,7 @@ void main() { test('Service extensions - exit', () async { // no test for _calling_ 'exit', because that should terminate the process! // Not expecting extension to be available for web platform. - expect(binding.extensions.containsKey('exit'), !isBrowser); + expect(binding.extensions.containsKey(FoundationServiceExtensions.exit.name), !isBrowser); }); test('Service extensions - platformOverride', () async { @@ -588,11 +588,11 @@ void main() { expect(binding.reassembled, 0); expect(defaultTargetPlatform, TargetPlatform.android); - result = await binding.testExtension('platformOverride', {}); + result = await binding.testExtension(FoundationServiceExtensions.platformOverride.name, {}); expect(result, {'value': 'android'}); expect(defaultTargetPlatform, TargetPlatform.android); expect(extensionChangedEvents, isEmpty); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'iOS'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'iOS'})); expect(result, {'value': 'iOS'}); expect(binding.reassembled, 1); expect(defaultTargetPlatform, TargetPlatform.iOS); @@ -600,7 +600,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'iOS'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'macOS'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'macOS'})); expect(result, {'value': 'macOS'}); expect(binding.reassembled, 2); expect(defaultTargetPlatform, TargetPlatform.macOS); @@ -608,7 +608,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'macOS'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'android'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'android'})); expect(result, {'value': 'android'}); expect(binding.reassembled, 3); expect(defaultTargetPlatform, TargetPlatform.android); @@ -616,7 +616,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'android'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'fuchsia'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'fuchsia'})); expect(result, {'value': 'fuchsia'}); expect(binding.reassembled, 4); expect(defaultTargetPlatform, TargetPlatform.fuchsia); @@ -624,7 +624,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'fuchsia'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'default'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'default'})); expect(result, {'value': 'android'}); expect(binding.reassembled, 5); expect(defaultTargetPlatform, TargetPlatform.android); @@ -632,7 +632,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'android'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'iOS'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'iOS'})); expect(result, {'value': 'iOS'}); expect(binding.reassembled, 6); expect(defaultTargetPlatform, TargetPlatform.iOS); @@ -640,7 +640,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'iOS'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'linux'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'linux'})); expect(result, {'value': 'linux'}); expect(binding.reassembled, 7); expect(defaultTargetPlatform, TargetPlatform.linux); @@ -648,7 +648,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'linux'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'windows'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'windows'})); expect(result, {'value': 'windows'}); expect(binding.reassembled, 8); expect(defaultTargetPlatform, TargetPlatform.windows); @@ -656,7 +656,7 @@ void main() { extensionChangedEvent = extensionChangedEvents.last; expect(extensionChangedEvent['extension'], 'ext.flutter.platformOverride'); expect(extensionChangedEvent['value'], 'windows'); - result = await hasReassemble(binding.testExtension('platformOverride', {'value': 'bogus'})); + result = await hasReassemble(binding.testExtension(FoundationServiceExtensions.platformOverride.name, {'value': 'bogus'})); expect(result, {'value': 'android'}); expect(binding.reassembled, 9); expect(defaultTargetPlatform, TargetPlatform.android); @@ -674,11 +674,11 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugRepaintRainbowEnabled, false); - result = await binding.testExtension('repaintRainbow', {}); + result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, {}); expect(result, {'enabled': 'false'}); expect(debugRepaintRainbowEnabled, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('repaintRainbow', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -687,11 +687,11 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'true'}); expect(debugRepaintRainbowEnabled, true); - result = await binding.testExtension('repaintRainbow', {}); + result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, {}); expect(result, {'enabled': 'true'}); expect(debugRepaintRainbowEnabled, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('repaintRainbow', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, {'enabled': 'false'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -704,7 +704,7 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'false'}); expect(debugRepaintRainbowEnabled, false); - result = await binding.testExtension('repaintRainbow', {}); + result = await binding.testExtension(RenderingServiceExtensions.repaintRainbow.name, {}); expect(result, {'enabled': 'false'}); expect(debugRepaintRainbowEnabled, false); expect(binding.frameScheduled, isFalse); @@ -717,11 +717,11 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugDisableClipLayers, false); - result = await binding.testExtension('debugDisableClipLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisableClipLayers, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisableClipLayers', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -734,11 +734,11 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'true'}); expect(debugDisableClipLayers, true); - result = await binding.testExtension('debugDisableClipLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, {}); expect(result, {'enabled': 'true'}); expect(debugDisableClipLayers, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisableClipLayers', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -746,7 +746,7 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'false'}); expect(debugDisableClipLayers, false); - result = await binding.testExtension('debugDisableClipLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableClipLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisableClipLayers, false); expect(binding.frameScheduled, isFalse); @@ -759,11 +759,11 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugDisablePhysicalShapeLayers, false); - result = await binding.testExtension('debugDisablePhysicalShapeLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisablePhysicalShapeLayers, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisablePhysicalShapeLayers', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -776,11 +776,11 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'true'}); expect(debugDisablePhysicalShapeLayers, true); - result = await binding.testExtension('debugDisablePhysicalShapeLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, {}); expect(result, {'enabled': 'true'}); expect(debugDisablePhysicalShapeLayers, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisablePhysicalShapeLayers', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -788,7 +788,7 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'false'}); expect(debugDisablePhysicalShapeLayers, false); - result = await binding.testExtension('debugDisablePhysicalShapeLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisablePhysicalShapeLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisablePhysicalShapeLayers, false); expect(binding.frameScheduled, isFalse); @@ -801,11 +801,11 @@ void main() { expect(binding.frameScheduled, isFalse); expect(debugDisableOpacityLayers, false); - result = await binding.testExtension('debugDisableOpacityLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisableOpacityLayers, false); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisableOpacityLayers', {'enabled': 'true'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, {'enabled': 'true'}); completed = false; pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); @@ -818,11 +818,11 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'true'}); expect(debugDisableOpacityLayers, true); - result = await binding.testExtension('debugDisableOpacityLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, {}); expect(result, {'enabled': 'true'}); expect(debugDisableOpacityLayers, true); expect(binding.frameScheduled, isFalse); - pendingResult = binding.testExtension('debugDisableOpacityLayers', {'enabled': 'false'}); + pendingResult = binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, {'enabled': 'false'}); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); await binding.doFrame(); @@ -830,7 +830,7 @@ void main() { result = await pendingResult; expect(result, {'enabled': 'false'}); expect(debugDisableOpacityLayers, false); - result = await binding.testExtension('debugDisableOpacityLayers', {}); + result = await binding.testExtension(RenderingServiceExtensions.debugDisableOpacityLayers.name, {}); expect(result, {'enabled': 'false'}); expect(debugDisableOpacityLayers, false); expect(binding.frameScheduled, isFalse); @@ -843,7 +843,7 @@ void main() { completed = false; expect(binding.reassembled, 0); - pendingResult = binding.testExtension('reassemble', {}); + pendingResult = binding.testExtension(FoundationServiceExtensions.reassemble.name, {}); pendingResult.whenComplete(() { completed = true; }); await binding.flushMicrotasks(); expect(binding.frameScheduled, isTrue); @@ -863,52 +863,30 @@ void main() { // The performance overlay service extension is disabled on the web. if (kIsWeb) { - expect(binding.extensions.containsKey('showPerformanceOverlay'), isFalse); + expect(binding.extensions.containsKey(WidgetsServiceExtensions.showPerformanceOverlay.name), isFalse); return; } expect(binding.frameScheduled, isFalse); expect(WidgetsApp.showPerformanceOverlayOverride, false); - result = await binding.testExtension('showPerformanceOverlay', {}); + result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, {}); expect(result, {'enabled': 'false'}); expect(WidgetsApp.showPerformanceOverlayOverride, false); - result = await binding.testExtension('showPerformanceOverlay', {'enabled': 'true'}); + result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, {'enabled': 'true'}); expect(result, {'enabled': 'true'}); expect(WidgetsApp.showPerformanceOverlayOverride, true); - result = await binding.testExtension('showPerformanceOverlay', {}); + result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, {}); expect(result, {'enabled': 'true'}); expect(WidgetsApp.showPerformanceOverlayOverride, true); - result = await binding.testExtension('showPerformanceOverlay', {'enabled': 'false'}); + result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, {'enabled': 'false'}); expect(result, {'enabled': 'false'}); expect(WidgetsApp.showPerformanceOverlayOverride, false); - result = await binding.testExtension('showPerformanceOverlay', {}); + result = await binding.testExtension(WidgetsServiceExtensions.showPerformanceOverlay.name, {}); expect(result, {'enabled': 'false'}); expect(WidgetsApp.showPerformanceOverlayOverride, false); expect(binding.frameScheduled, isFalse); }); - test('Service extensions - debugWidgetInspector', () async { - Map result; - expect(binding.frameScheduled, isFalse); - expect(WidgetsApp.debugShowWidgetInspectorOverride, false); - result = await binding.testExtension('debugWidgetInspector', {}); - expect(result, {'enabled': 'false'}); - expect(WidgetsApp.debugShowWidgetInspectorOverride, false); - result = await binding.testExtension('debugWidgetInspector', {'enabled': 'true'}); - expect(result, {'enabled': 'true'}); - expect(WidgetsApp.debugShowWidgetInspectorOverride, true); - result = await binding.testExtension('debugWidgetInspector', {}); - expect(result, {'enabled': 'true'}); - expect(WidgetsApp.debugShowWidgetInspectorOverride, true); - result = await binding.testExtension('debugWidgetInspector', {'enabled': 'false'}); - expect(result, {'enabled': 'false'}); - expect(WidgetsApp.debugShowWidgetInspectorOverride, false); - result = await binding.testExtension('debugWidgetInspector', {}); - expect(result, {'enabled': 'false'}); - expect(WidgetsApp.debugShowWidgetInspectorOverride, false); - expect(binding.frameScheduled, isFalse); - }); - test('Service extensions - timeDilation', () async { final Iterable> extensionChangedEvents = binding.getServiceExtensionStateChangedEvents('ext.flutter.timeDilation'); Map extensionChangedEvent; @@ -947,7 +925,7 @@ void main() { test('Service extensions - brightnessOverride', () async { Map result; - result = await binding.testExtension('brightnessOverride', {}); + result = await binding.testExtension(FoundationServiceExtensions.brightnessOverride.name, {}); final String brightnessValue = result['value'] as String; expect(brightnessValue, 'Brightness.light'); @@ -955,26 +933,26 @@ void main() { test('Service extensions - activeDevToolsServerAddress', () async { Map result; - result = await binding.testExtension('activeDevToolsServerAddress', {}); + result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, {}); String serverAddress = result['value'] as String; expect(serverAddress, ''); - result = await binding.testExtension('activeDevToolsServerAddress', {'value': 'http://127.0.0.1:9101'}); + result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, {'value': 'http://127.0.0.1:9101'}); serverAddress = result['value'] as String; expect(serverAddress, 'http://127.0.0.1:9101'); - result = await binding.testExtension('activeDevToolsServerAddress', {'value': 'http://127.0.0.1:9102'}); + result = await binding.testExtension(FoundationServiceExtensions.activeDevToolsServerAddress.name, {'value': 'http://127.0.0.1:9102'}); serverAddress = result['value'] as String; expect(serverAddress, 'http://127.0.0.1:9102'); }); test('Service extensions - connectedVmServiceUri', () async { Map result; - result = await binding.testExtension('connectedVmServiceUri', {}); + result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, {}); String serverAddress = result['value'] as String; expect(serverAddress, ''); - result = await binding.testExtension('connectedVmServiceUri', {'value': 'http://127.0.0.1:54669/kMUMseKAnog=/'}); + result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, {'value': 'http://127.0.0.1:54669/kMUMseKAnog=/'}); serverAddress = result['value'] as String; expect(serverAddress, 'http://127.0.0.1:54669/kMUMseKAnog=/'); - result = await binding.testExtension('connectedVmServiceUri', {'value': 'http://127.0.0.1:54000/kMUMseKAnog=/'}); + result = await binding.testExtension(FoundationServiceExtensions.connectedVmServiceUri.name, {'value': 'http://127.0.0.1:54000/kMUMseKAnog=/'}); serverAddress = result['value'] as String; expect(serverAddress, 'http://127.0.0.1:54000/kMUMseKAnog=/'); }); diff --git a/packages/flutter/test/material/icons_test.dart b/packages/flutter/test/material/icons_test.dart index a2a792aef8cc3..483be01ec82ce 100644 --- a/packages/flutter/test/material/icons_test.dart +++ b/packages/flutter/test/material/icons_test.dart @@ -122,6 +122,27 @@ void main() { await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample3.png')); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998 + + // Regression test for https://github.com/flutter/flutter/issues/103202. + testWidgets('Another sample of icons look as expected', (WidgetTester tester) async { + await _loadIconFont(); + + await tester.pumpWidget(MaterialApp( + home: IconTheme( + data: const IconThemeData(size: 200), + child: Wrap( + children: const [ + Icon(Icons.repeat_on), + Icon(Icons.repeat_on_outlined), + Icon(Icons.repeat_on_rounded), + Icon(Icons.repeat_on_sharp), + ], + ), + ), + )); + + await expectLater(find.byType(Wrap), matchesGoldenFile('test.icons.sample4.png')); + }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998 } // Loads the cached material icon font. diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart index 71cbb321dc472..5e2e0fba31e03 100644 --- a/packages/flutter/test/material/theme_data_test.dart +++ b/packages/flutter/test/material/theme_data_test.dart @@ -650,7 +650,6 @@ void main() { useMaterial3: false, visualDensity: VisualDensity.standard, // COLOR - bottomAppBarColor: Colors.black, canvasColor: Colors.black, cardColor: Colors.black, colorScheme: const ColorScheme.light(), @@ -725,6 +724,7 @@ void main() { selectedRowColor: Colors.black, errorColor: Colors.black, backgroundColor: Colors.black, + bottomAppBarColor: Colors.black, ); final SliderThemeData otherSliderTheme = SliderThemeData.fromPrimaryColors( @@ -762,7 +762,6 @@ void main() { visualDensity: VisualDensity.standard, // COLOR - bottomAppBarColor: Colors.white, canvasColor: Colors.white, cardColor: Colors.white, colorScheme: const ColorScheme.light(), @@ -840,6 +839,7 @@ void main() { selectedRowColor: Colors.white, errorColor: Colors.white, backgroundColor: Colors.white, + bottomAppBarColor: Colors.white, ); final ThemeData themeDataCopy = theme.copyWith( @@ -862,7 +862,6 @@ void main() { visualDensity: otherTheme.visualDensity, // COLOR - bottomAppBarColor: otherTheme.bottomAppBarColor, canvasColor: otherTheme.canvasColor, cardColor: otherTheme.cardColor, colorScheme: otherTheme.colorScheme, @@ -940,6 +939,7 @@ void main() { selectedRowColor: otherTheme.selectedRowColor, errorColor: otherTheme.errorColor, backgroundColor: otherTheme.backgroundColor, + bottomAppBarColor: otherTheme.bottomAppBarColor, ); // For the sanity of the reader, make sure these properties are in the same @@ -961,7 +961,6 @@ void main() { expect(themeDataCopy.visualDensity, equals(otherTheme.visualDensity)); // COLOR - expect(themeDataCopy.bottomAppBarColor, equals(otherTheme.bottomAppBarColor)); expect(themeDataCopy.canvasColor, equals(otherTheme.canvasColor)); expect(themeDataCopy.cardColor, equals(otherTheme.cardColor)); expect(themeDataCopy.colorScheme, equals(otherTheme.colorScheme)); @@ -1044,6 +1043,7 @@ void main() { expect(themeDataCopy.selectedRowColor, equals(otherTheme.selectedRowColor)); expect(themeDataCopy.errorColor, equals(otherTheme.errorColor)); expect(themeDataCopy.backgroundColor, equals(otherTheme.backgroundColor)); + expect(themeDataCopy.bottomAppBarColor, equals(otherTheme.bottomAppBarColor)); }); testWidgets('ThemeData.toString has less than 200 characters output', (WidgetTester tester) async { @@ -1109,7 +1109,6 @@ void main() { 'shadowColor', 'canvasColor', 'scaffoldBackgroundColor', - 'bottomAppBarColor', 'cardColor', 'dividerColor', 'highlightColor', @@ -1175,6 +1174,7 @@ void main() { 'selectedRowColor', 'errorColor', 'backgroundColor', + 'bottomAppBarColor', }; final DiagnosticPropertiesBuilder properties = DiagnosticPropertiesBuilder(); diff --git a/packages/flutter/test/painting/text_style_test.dart b/packages/flutter/test/painting/text_style_test.dart index 60da595bf6e2a..9038248e5f1c5 100644 --- a/packages/flutter/test/painting/text_style_test.dart +++ b/packages/flutter/test/painting/text_style_test.dart @@ -304,6 +304,23 @@ void main() { expect(s10.fontFamilyFallback, []); }); + test('TextStyle package font merge', () { + const TextStyle s1 = TextStyle(package: 'p', fontFamily: 'font1', fontFamilyFallback: ['fallback1']); + const TextStyle s2 = TextStyle(package: 'p', fontFamily: 'font2', fontFamilyFallback: ['fallback2']); + + final TextStyle emptyMerge = const TextStyle().merge(s1); + expect(emptyMerge.fontFamily, 'packages/p/font1'); + expect(emptyMerge.fontFamilyFallback, ['packages/p/fallback1']); + + final TextStyle lerp1 = TextStyle.lerp(s1, s2, 0)!; + expect(lerp1.fontFamily, 'packages/p/font1'); + expect(lerp1.fontFamilyFallback, ['packages/p/fallback1']); + + final TextStyle lerp2 = TextStyle.lerp(s1, s2, 1.0)!; + expect(lerp2.fontFamily, 'packages/p/font2'); + expect(lerp2.fontFamilyFallback, ['packages/p/fallback2']); + }); + test('TextStyle font family fallback', () { const TextStyle s1 = TextStyle(fontFamilyFallback: ['Roboto', 'test']); expect(s1.fontFamilyFallback![0], 'Roboto'); diff --git a/packages/flutter/test/widgets/fade_in_image_test.dart b/packages/flutter/test/widgets/fade_in_image_test.dart index ec1bb271f4384..c5078a8be6fe4 100644 --- a/packages/flutter/test/widgets/fade_in_image_test.dart +++ b/packages/flutter/test/widgets/fade_in_image_test.dart @@ -199,6 +199,44 @@ Future main() async { expect(parts.target.opacity, 1); }); + // Regression test for https://github.com/flutter/flutter/issues/111011 + testWidgets("FadeInImage's image obeys gapless playback when first image is cached but second isn't", + (WidgetTester tester) async { + final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage); + final TestImageProvider imageProvider = TestImageProvider(targetImage); + final TestImageProvider secondImageProvider = TestImageProvider(replacementImage); + + // Pre-cache the initial image. + imageProvider.resolve(ImageConfiguration.empty); + imageProvider.complete(); + placeholderProvider.complete(); + + await tester.pumpWidget(FadeInImage( + placeholder: placeholderProvider, + image: imageProvider, + )); + await tester.pumpAndSettle(); + + await tester.pumpWidget(FadeInImage( + placeholder: placeholderProvider, + image: secondImageProvider, + )); + + FadeInImageParts parts = findFadeInImage(tester); + // Continually shows previously loaded image until the new image provider provides the image. + expect(parts.placeholder, isNull); + expect(parts.target.rawImage.image!.isCloneOf(targetImage), isTrue); + expect(parts.target.opacity, 1); + + // Now, provide the image. + secondImageProvider.complete(); + await tester.pump(); + + parts = findFadeInImage(tester); + expect(parts.target.rawImage.image!.isCloneOf(replacementImage), isTrue); + expect(parts.target.opacity, 1); + }); + testWidgets("FadeInImage's placeholder obeys gapless playback", (WidgetTester tester) async { final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage); final TestImageProvider secondPlaceholderProvider = TestImageProvider(replacementImage); diff --git a/packages/flutter/test/widgets/icon_test.dart b/packages/flutter/test/widgets/icon_test.dart index 1e59741044b13..93cb51147d7f2 100644 --- a/packages/flutter/test/widgets/icon_test.dart +++ b/packages/flutter/test/widgets/icon_test.dart @@ -269,7 +269,7 @@ void main() { ]); }); - testWidgets('Theme-level fill, weight, grade, and optical size can be overriden', (WidgetTester tester) async { + testWidgets('Theme-level fill, weight, grade, and optical size can be overridden', (WidgetTester tester) async { await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, diff --git a/packages/flutter/test_fixes/material.dart b/packages/flutter/test_fixes/material.dart index cdd40e0cb5ba8..40f9545c4355e 100644 --- a/packages/flutter/test_fixes/material.dart +++ b/packages/flutter/test_fixes/material.dart @@ -688,4 +688,10 @@ void main() { themeData = ThemeData(backgroundColor: Colors.grey, errorColor: Colors.red); themeData = ThemeData.raw(backgroundColor: Colors.grey, errorColor: Colors.red); themeData = themeData.copyWith(backgroundColor: Colors.grey, errorColor: Colors.red); + + // Changes made in https://github.com/flutter/flutter/pull/111080 + ThemeData themeData = ThemeData(); + themeData = ThemeData(bottomAppBarColor: Colors.green); + themeData = ThemeData.raw(bottomAppBarColor: Colors.green); + themeData = ThemeData.copyWith(bottomAppBarColor: Colors.green); } diff --git a/packages/flutter/test_fixes/material.dart.expect b/packages/flutter/test_fixes/material.dart.expect index 4e06598edfbb3..7f8763a324156 100644 --- a/packages/flutter/test_fixes/material.dart.expect +++ b/packages/flutter/test_fixes/material.dart.expect @@ -892,4 +892,10 @@ void main() { themeData = ThemeData(colorScheme: ColorScheme(error: Colors.red).copyWith(background: Colors.grey)); themeData = ThemeData.raw(colorScheme: ColorScheme(error: Colors.red).copyWith(background: Colors.grey)); themeData = themeData.copyWith(colorScheme: ColorScheme(error: Colors.red).copyWith(background: Colors.grey)); + + // Changes made in https://github.com/flutter/flutter/pull/111080 + ThemeData themeData = ThemeData(); + themeData = ThemeData(bottomAppBarTheme: BottomAppBarTheme(color: Colors.green)); + themeData = ThemeData.raw(bottomAppBarTheme: BottomAppBarTheme(color: Colors.green)); + themeData = ThemeData.copyWith(bottomAppBarTheme: BottomAppBarTheme(color: Colors.green)); } diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart index 8229dca022263..b10cfe091a1b1 100644 --- a/packages/flutter_test/lib/src/matchers.dart +++ b/packages/flutter_test/lib/src/matchers.dart @@ -2272,10 +2272,10 @@ class _MatchesSemanticsData extends Matcher { .toList(); if (expectedActions.isNotEmpty) { - description.add(' with actions: ').addDescriptionOf(expectedActions); + description.add(' with actions: ${_createEnumsSummary(expectedActions)} '); } if (notExpectedActions.isNotEmpty) { - description.add(' without actions: ').addDescriptionOf(notExpectedActions); + description.add(' without actions: ${_createEnumsSummary(notExpectedActions)} '); } } if (flags.isNotEmpty) { @@ -2289,10 +2289,10 @@ class _MatchesSemanticsData extends Matcher { .toList(); if (expectedFlags.isNotEmpty) { - description.add(' with flags: ').addDescriptionOf(expectedFlags); + description.add(' with flags: ${_createEnumsSummary(expectedFlags)} '); } if (notExpectedFlags.isNotEmpty) { - description.add(' without flags: ').addDescriptionOf(notExpectedFlags); + description.add(' without flags: ${_createEnumsSummary(notExpectedFlags)} '); } } if (textDirection != null) { @@ -2434,18 +2434,24 @@ class _MatchesSemanticsData extends Matcher { return failWithDescription(matchState, 'maxValueLength was: ${data.maxValueLength}'); } if (actions.isNotEmpty) { + final List unexpectedActions = []; + final List missingActions = []; for (final MapEntry actionEntry in actions.entries) { final ui.SemanticsAction action = actionEntry.key; final bool actionExpected = actionEntry.value; final bool actionPresent = (action.index & data.actions) == action.index; if (actionPresent != actionExpected) { - final List actionSummary = [ - for (final int action in SemanticsAction.values.keys) - if ((data.actions & action) != 0) describeEnum(action), - ]; - return failWithDescription(matchState, 'actions were: $actionSummary'); + if(actionExpected) { + missingActions.add(action); + } else { + unexpectedActions.add(action); + } } } + + if (unexpectedActions.isNotEmpty || missingActions.isNotEmpty) { + return failWithDescription(matchState, 'missing actions: ${_createEnumsSummary(missingActions)} unexpected actions: ${_createEnumsSummary(unexpectedActions)}'); + } } if (customActions != null || hintOverrides != null) { final List providedCustomActions = data.customSemanticsActionIds?.map((int id) { @@ -2473,18 +2479,24 @@ class _MatchesSemanticsData extends Matcher { } } if (flags.isNotEmpty) { + final List unexpectedFlags = []; + final List missingFlags = []; for (final MapEntry flagEntry in flags.entries) { final ui.SemanticsFlag flag = flagEntry.key; final bool flagExpected = flagEntry.value; final bool flagPresent = flag.index & data.flags == flag.index; if (flagPresent != flagExpected) { - final List flagSummary = [ - for (final int flag in SemanticsFlag.values.keys) - if ((data.flags & flag) != 0) describeEnum(flag), - ]; - return failWithDescription(matchState, 'flags were: $flagSummary'); + if(flagExpected) { + missingFlags.add(flag); + } else { + unexpectedFlags.add(flag); + } } } + + if (unexpectedFlags.isNotEmpty || missingFlags.isNotEmpty) { + return failWithDescription(matchState, 'missing flags: ${_createEnumsSummary(missingFlags)} unexpected flags: ${_createEnumsSummary(unexpectedFlags)}'); + } } bool allMatched = true; if (children != null) { @@ -2512,6 +2524,11 @@ class _MatchesSemanticsData extends Matcher { ) { return mismatchDescription.add(matchState['failure'] as String); } + + static String _createEnumsSummary(List enums) { + assert(T == SemanticsAction || T == SemanticsFlag, 'This method is only intended for lists of SemanticsActions or SemanticsFlags.'); + return '[${enums.map(describeEnum).join(', ')}]'; + } } class _MatchesAccessibilityGuideline extends AsyncMatcher { diff --git a/packages/flutter_test/test/matchers_test.dart b/packages/flutter_test/test/matchers_test.dart index b4b37b63d3c17..6bbaf5650e4eb 100644 --- a/packages/flutter_test/test/matchers_test.dart +++ b/packages/flutter_test/test/matchers_test.dart @@ -733,6 +733,62 @@ void main() { )); handle.dispose(); }); + + testWidgets('failure does not throw unexpected errors', (WidgetTester tester) async { + final SemanticsHandle handle = tester.ensureSemantics(); + addTearDown(() => handle.dispose()); + + const Key key = Key('semantics'); + await tester.pumpWidget(Semantics( + key: key, + namesRoute: true, + header: true, + button: true, + link: true, + onTap: () { }, + onLongPress: () { }, + label: 'foo', + hint: 'bar', + value: 'baz', + increasedValue: 'a', + decreasedValue: 'b', + textDirection: TextDirection.rtl, + onTapHint: 'scan', + onLongPressHint: 'fill', + customSemanticsActions: { + const CustomSemanticsAction(label: 'foo'): () { }, + const CustomSemanticsAction(label: 'bar'): () { }, + }, + )); + + // This should fail due to the mis-match between the `namesRoute` value. + void failedExpectation() => expect(tester.getSemantics(find.byKey(key)), + matchesSemantics( + // Adding the explicit `false` for test readability + // ignore: avoid_redundant_argument_values + namesRoute: false, + label: 'foo', + hint: 'bar', + value: 'baz', + increasedValue: 'a', + decreasedValue: 'b', + textDirection: TextDirection.rtl, + hasTapAction: true, + hasLongPressAction: true, + isButton: true, + isLink: true, + isHeader: true, + onTapHint: 'scan', + onLongPressHint: 'fill', + customActions: [ + const CustomSemanticsAction(label: 'foo'), + const CustomSemanticsAction(label: 'bar'), + ], + ), + ); + + expect(failedExpectation, throwsA(isA())); + }); }); group('containsSemantics', () { @@ -1173,6 +1229,60 @@ void main() { expect(node, containsSemantics(customActions: [action])); }); + + testWidgets('failure does not throw unexpected errors', (WidgetTester tester) async { + final SemanticsHandle handle = tester.ensureSemantics(); + addTearDown(() => handle.dispose()); + + const Key key = Key('semantics'); + await tester.pumpWidget(Semantics( + key: key, + namesRoute: true, + header: true, + button: true, + link: true, + onTap: () { }, + onLongPress: () { }, + label: 'foo', + hint: 'bar', + value: 'baz', + increasedValue: 'a', + decreasedValue: 'b', + textDirection: TextDirection.rtl, + onTapHint: 'scan', + onLongPressHint: 'fill', + customSemanticsActions: { + const CustomSemanticsAction(label: 'foo'): () { }, + const CustomSemanticsAction(label: 'bar'): () { }, + }, + )); + + // This should fail due to the mis-match between the `namesRoute` value. + void failedExpectation() => expect(tester.getSemantics(find.byKey(key)), + containsSemantics( + label: 'foo', + hint: 'bar', + value: 'baz', + increasedValue: 'a', + decreasedValue: 'b', + textDirection: TextDirection.rtl, + hasTapAction: true, + hasLongPressAction: true, + isButton: true, + isLink: true, + isHeader: true, + namesRoute: false, + onTapHint: 'scan', + onLongPressHint: 'fill', + customActions: [ + const CustomSemanticsAction(label: 'foo'), + const CustomSemanticsAction(label: 'bar'), + ], + ), + ); + + expect(failedExpectation, throwsA(isA())); + }); }); group('findsAtLeastNWidgets', () { diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index b999ea482bd72..e80f477c3ae25 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -192,7 +192,6 @@ class CreateCommand extends CreateBase { } validateOutputDirectoryArg(); - String? sampleCode; final String? sampleArgument = stringArg('sample'); if (sampleArgument != null) { @@ -255,7 +254,29 @@ class CreateCommand extends CreateBase { } final String dartSdk = globals.cache.dartSdkBuild; - final bool includeIos = featureFlags.isIOSEnabled && platforms.contains('ios'); + final bool includeIos; + final bool includeAndroid; + final bool includeWeb; + final bool includeLinux; + final bool includeMacos; + final bool includeWindows; + if (template == FlutterProjectType.module) { + // The module template only supports iOS and Android. + includeIos = true; + includeAndroid = true; + includeWeb = false; + includeLinux = false; + includeMacos = false; + includeWindows = false; + } else { + includeIos = featureFlags.isIOSEnabled && platforms.contains('ios'); + includeAndroid = featureFlags.isAndroidEnabled && platforms.contains('android'); + includeWeb = featureFlags.isWebEnabled && platforms.contains('web'); + includeLinux = featureFlags.isLinuxEnabled && platforms.contains('linux'); + includeMacos = featureFlags.isMacOSEnabled && platforms.contains('macos'); + includeWindows = featureFlags.isWindowsEnabled && platforms.contains('windows'); + } + String? developmentTeam; if (includeIos) { developmentTeam = await getCodeSigningIdentityDevelopmentTeam( @@ -282,11 +303,11 @@ class CreateCommand extends CreateBase { iosLanguage: stringArgDeprecated('ios-language'), iosDevelopmentTeam: developmentTeam, ios: includeIos, - android: featureFlags.isAndroidEnabled && platforms.contains('android'), - web: featureFlags.isWebEnabled && platforms.contains('web'), - linux: featureFlags.isLinuxEnabled && platforms.contains('linux'), - macos: featureFlags.isMacOSEnabled && platforms.contains('macos'), - windows: featureFlags.isWindowsEnabled && platforms.contains('windows'), + android: includeAndroid, + web: includeWeb, + linux: includeLinux, + macos: includeMacos, + windows: includeWindows, // Enable null safety everywhere. dartSdkVersionBounds: "'>=$dartSdk <3.0.0'", implementationTests: boolArgDeprecated('implementation-tests'), @@ -309,6 +330,7 @@ class CreateCommand extends CreateBase { final Directory relativeDir = globals.fs.directory(projectDirPath); int generatedFileCount = 0; + final PubContext pubContext; switch (template) { case FlutterProjectType.app: generatedFileCount += await generateApp( @@ -319,6 +341,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.create; break; case FlutterProjectType.skeleton: generatedFileCount += await generateApp( @@ -329,6 +352,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, generateMetadata: false, ); + pubContext = PubContext.create; break; case FlutterProjectType.module: generatedFileCount += await _generateModule( @@ -337,6 +361,7 @@ class CreateCommand extends CreateBase { overwrite: overwrite, printStatusWhenWriting: !creatingNewProject, ); + pubContext = PubContext.create; break; case FlutterProjectType.package: generatedFileCount += await _generatePackage( @@ -345,6 +370,7 @@ class CreateCommand extends CreateBase { overwrite: overwrite, printStatusWhenWriting: !creatingNewProject, ); + pubContext = PubContext.createPackage; break; case FlutterProjectType.plugin: generatedFileCount += await _generateMethodChannelPlugin( @@ -354,6 +380,7 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.createPlugin; break; case FlutterProjectType.ffiPlugin: generatedFileCount += await _generateFfiPlugin( @@ -363,8 +390,26 @@ class CreateCommand extends CreateBase { printStatusWhenWriting: !creatingNewProject, projectType: template, ); + pubContext = PubContext.createPlugin; break; } + + if (boolArgDeprecated('pub')) { + final FlutterProject project = FlutterProject.fromDirectory(relativeDir); + await pub.get( + context: pubContext, + project: project, + offline: boolArgDeprecated('offline'), + ); + await project.ensureReadyForPlatformSpecificTooling( + androidPlatform: includeAndroid, + iosPlatform: includeIos, + linuxPlatform: includeLinux, + macOSPlatform: includeMacos, + windowsPlatform: includeWindows, + webPlatform: includeWeb, + ); + } if (sampleCode != null) { generatedFileCount += _applySample(relativeDir, sampleCode); } @@ -447,18 +492,6 @@ Your $application code is in $relativeAppMain. overwrite: overwrite, printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.create, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - final FlutterProject project = FlutterProject.fromDirectory(directory); - await project.ensureReadyForPlatformSpecificTooling( - androidPlatform: true, - iosPlatform: true, - ); - } return generatedCount; } @@ -480,13 +513,6 @@ Your $application code is in $relativeAppMain. overwrite: overwrite, printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPackage, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } return generatedCount; } @@ -526,14 +552,6 @@ Your $application code is in $relativeAppMain. printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPlugin, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } - final FlutterProject project = FlutterProject.fromDirectory(directory); final bool generateAndroid = templateContext['android'] == true; if (generateAndroid) { @@ -604,14 +622,6 @@ Your $application code is in $relativeAppMain. printStatusWhenWriting: printStatusWhenWriting, ); - if (boolArgDeprecated('pub')) { - await pub.get( - context: PubContext.createPlugin, - directory: directory.path, - offline: boolArgDeprecated('offline'), - ); - } - final FlutterProject project = FlutterProject.fromDirectory(directory); final bool generateAndroid = templateContext['android'] == true; if (generateAndroid) { diff --git a/packages/flutter_tools/lib/src/commands/create_base.dart b/packages/flutter_tools/lib/src/commands/create_base.dart index a131d6cd119c9..2f11b87b4f060 100644 --- a/packages/flutter_tools/lib/src/commands/create_base.dart +++ b/packages/flutter_tools/lib/src/commands/create_base.dart @@ -17,7 +17,6 @@ import '../build_system/build_system.dart'; import '../cache.dart'; import '../convert.dart'; import '../dart/generate_synthetic_packages.dart'; -import '../dart/pub.dart'; import '../flutter_project_metadata.dart'; import '../globals.dart' as globals; import '../project.dart'; @@ -549,24 +548,6 @@ abstract class CreateBase extends FlutterCommand { environment: environment, buildSystem: globals.buildSystem, ); - - await pub.get( - context: PubContext.create, - directory: directory.path, - offline: boolArgDeprecated('offline'), - // For templates that use the l10n localization tooling, make sure - // importing the generated package works right after `flutter create`. - generateSyntheticPackage: true, - ); - - await project.ensureReadyForPlatformSpecificTooling( - androidPlatform: androidPlatform, - iosPlatform: iosPlatform, - linuxPlatform: linuxPlatform, - macOSPlatform: macOSPlatform, - windowsPlatform: windowsPlatform, - webPlatform: webPlatform, - ); } final List platformsForMigrateConfig = [SupportedPlatform.root]; if (androidPlatform) { diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 5b1d8f4ebdd94..3e3f9ccb979f0 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -1541,7 +1541,7 @@ class AppRunLogger extends DelegatingLogger { } @override - bool get supportsColor => throw UnimplementedError(); + bool get supportsColor => false; @override bool get hasTerminal => false; diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index f360cc5f87b22..14503a03b2f52 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -139,11 +139,10 @@ class PackagesGetCommand extends FlutterCommand { try { await pub.get( context: PubContext.pubGet, - directory: directory, + project: flutterProject, upgrade: upgrade, shouldSkipThirdPartyGenerator: false, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: flutterProject.manifest.generateSyntheticPackage, ); pubGetTimer.stop(); globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); @@ -172,13 +171,14 @@ class PackagesGetCommand extends FlutterCommand { } final FlutterProject rootProject = FlutterProject.fromDirectory(globals.fs.directory(target)); + // This will also resolve dependencies for the example folder, await _runPubGet(target, rootProject); - await rootProject.regeneratePlatformSpecificTooling(); - // Get/upgrade packages in example app as well + // We need to regenerate the platform specific tooling for both the project + // itself and example (if present). + await rootProject.regeneratePlatformSpecificTooling(); if (rootProject.hasExampleApp && rootProject.example.pubspecFile.existsSync()) { final FlutterProject exampleProject = rootProject.example; - await _runPubGet(exampleProject.directory.path, exampleProject); await exampleProject.regeneratePlatformSpecificTooling(); } @@ -211,7 +211,7 @@ class PackagesTestCommand extends FlutterCommand { @override Future runCommand() async { - await pub.batch(['run', 'test', ...argResults!.rest], context: PubContext.runTest, retry: false); + await pub.batch(['run', 'test', ...argResults!.rest], context: PubContext.runTest); return FlutterCommandResult.success(); } } diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart index dbef897c9718e..ef70ceeef14d7 100644 --- a/packages/flutter_tools/lib/src/commands/update_packages.dart +++ b/packages/flutter_tools/lib/src/commands/update_packages.dart @@ -16,6 +16,7 @@ import '../base/task_queue.dart'; import '../cache.dart'; import '../dart/pub.dart'; import '../globals.dart' as globals; +import '../project.dart'; import '../runner/flutter_command.dart'; /// Map from package name to package version, used to artificially pin a pub @@ -399,7 +400,7 @@ class UpdatePackagesCommand extends FlutterCommand { // needed packages to the pub cache, upgrading if requested. await pub.get( context: PubContext.updatePackages, - directory: tempDir.path, + project: FlutterProject.fromDirectory(tempDir), upgrade: doUpgrade, offline: boolArgDeprecated('offline'), flutterRootOverride: temporaryFlutterSdk?.path, @@ -422,7 +423,6 @@ class UpdatePackagesCommand extends FlutterCommand { context: PubContext.updatePackages, directory: tempDir.path, filter: tree.fill, - retry: false, // errors here are usually fatal since we're not hitting the network ); } } finally { @@ -502,7 +502,7 @@ class UpdatePackagesCommand extends FlutterCommand { stopwatch.start(); await pub.get( context: PubContext.updatePackages, - directory: dir.path, + project: FlutterProject.fromDirectory(dir), // All dependencies should already have been downloaded by the fake // package, so the concurrent checks can all happen offline. offline: true, diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 4841f29e37d62..158597cac93c8 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -12,6 +12,7 @@ import '../cache.dart'; import '../dart/pub.dart'; import '../globals.dart' as globals; import '../persistent_tool_state.dart'; +import '../project.dart'; import '../runner/flutter_command.dart'; import '../version.dart'; import 'channel.dart'; @@ -303,7 +304,7 @@ class UpgradeCommandRunner { /// Update the engine repository and precache all artifacts. /// /// Check for and download any engine and pkg/ updates. We run the 'flutter' - /// shell script re-entrantly here so that it will download the updated + /// shell script reentrantly here so that it will download the updated /// Dart and so forth if necessary. Future precacheArtifacts() async { globals.printStatus(''); @@ -330,7 +331,7 @@ class UpgradeCommandRunner { globals.printStatus(''); await pub.get( context: PubContext.pubUpgrade, - directory: projectRoot, + project: FlutterProject.fromDirectory(globals.fs.directory(projectRoot)), upgrade: true, ); } diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index ca5369c55d34a..020efc5f7ead1 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -152,6 +152,7 @@ Future runInContext( logger: globals.logger, platform: globals.platform, osUtils: globals.os, + projectFactory: globals.projectFactory, ), CocoaPods: () => CocoaPods( fileSystem: globals.fs, @@ -312,6 +313,7 @@ Future runInContext( botDetector: globals.botDetector, platform: globals.platform, usage: globals.flutterUsage, + stdio: globals.stdio, ), Stdio: () => Stdio(), SystemClock: () => const SystemClock(), diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index c784f85cf0e1f..f64249d08309c 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -12,12 +12,14 @@ import '../base/common.dart'; import '../base/context.dart'; import '../base/file_system.dart'; import '../base/io.dart' as io; +import '../base/io.dart'; import '../base/logger.dart'; import '../base/platform.dart'; import '../base/process.dart'; import '../cache.dart'; import '../convert.dart'; import '../dart/package_map.dart'; +import '../project.dart'; import '../reporting/reporting.dart'; /// The [Pub] instance. @@ -148,9 +150,10 @@ abstract class Pub { required Platform platform, required BotDetector botDetector, required Usage usage, + required Stdio stdio, }) = _DefaultPub; - /// Runs `pub get`. + /// Runs `pub get` or `pub upgrade` for [project]. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -158,13 +161,13 @@ abstract class Pub { /// If [shouldSkipThirdPartyGenerator] is true, the overall pub get will be /// skipped if the package config file has a "generator" other than "pub". /// Defaults to true. + /// Will also resolve dependencies in the example folder if present. Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, - bool generateSyntheticPackage = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, @@ -177,9 +180,8 @@ abstract class Pub { /// the corresponding stream of this process, optionally applying filtering. /// The pub process will not receive anything on its stdin stream. /// - /// The `--trace` argument is passed to `pub` (by mutating the provided - /// `arguments` list) when `showTraceForErrors` is true, and when `showTraceForErrors` - /// is null/unset, and `isRunningOnBot` is true. + /// The `--trace` argument is passed to `pub` when `showTraceForErrors` + /// `isRunningOnBot` is true. /// /// [context] provides extra information to package server requests to /// understand usage. @@ -189,8 +191,6 @@ abstract class Pub { String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, }); /// Runs pub in 'interactive' mode. @@ -214,6 +214,7 @@ class _DefaultPub implements Pub { required Platform platform, required BotDetector botDetector, required Usage usage, + required Stdio stdio, }) : _fileSystem = fileSystem, _logger = logger, _platform = platform, @@ -223,7 +224,8 @@ class _DefaultPub implements Pub { logger: logger, processManager: processManager, ), - _processManager = processManager; + _processManager = processManager, + _stdio = stdio; final FileSystem _fileSystem; final Logger _logger; @@ -232,40 +234,40 @@ class _DefaultPub implements Pub { final BotDetector _botDetector; final Usage _usage; final ProcessManager _processManager; + final Stdio _stdio; @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - directory ??= _fileSystem.currentDirectory.path; - final File packageConfigFile = _fileSystem.file( - _fileSystem.path.join(directory, '.dart_tool', 'package_config.json')); + final String directory = project.directory.path; + final File packageConfigFile = project.packageConfigFile; final Directory generatedDirectory = _fileSystem.directory( _fileSystem.path.join(directory, '.dart_tool', 'flutter_gen')); final File lastVersion = _fileSystem.file( _fileSystem.path.join(directory, '.dart_tool', 'version')); final File currentVersion = _fileSystem.file( _fileSystem.path.join(Cache.flutterRoot!, 'version')); - final File pubspecYaml = _fileSystem.file( - _fileSystem.path.join(directory, 'pubspec.yaml')); + final File pubspecYaml = project.pubspecFile; final File pubLockFile = _fileSystem.file( _fileSystem.path.join(directory, 'pubspec.lock') ); - if (shouldSkipThirdPartyGenerator && packageConfigFile.existsSync()) { + if (shouldSkipThirdPartyGenerator && project.packageConfigFile.existsSync()) { Map packageConfigMap; try { packageConfigMap = jsonDecode( - packageConfigFile.readAsStringSync(), + project.packageConfigFile.readAsStringSync(), ) as Map; } on FormatException { packageConfigMap = {}; @@ -298,31 +300,118 @@ class _DefaultPub implements Pub { } final String command = upgrade ? 'upgrade' : 'get'; - final Status? status = printProgress ? _logger.startProgress( - 'Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...', - ) : null; final bool verbose = _logger.isVerbose; final List args = [ + if (_logger.supportsColor) + '--color', if (verbose) - '--verbose' - else - '--verbosity=warning', + '--verbose', + '--directory', + _fileSystem.path.relative(directory), ...[ command, - '--no-precompile', ], if (offline) '--offline', + '--example', ]; - try { - await batch( - args, - context: context, - directory: directory, - failureMessage: 'pub $command failed', - retry: !offline, - flutterRootOverride: flutterRootOverride, + await _runWithRetries( + args, + command: command, + context: context, + directory: directory, + failureMessage: 'pub $command failed', + retry: !offline, + flutterRootOverride: flutterRootOverride, + printProgress: printProgress + ); + + if (!packageConfigFile.existsSync()) { + throwToolExit('$directory: pub did not create .dart_tools/package_config.json file.'); + } + lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); + await _updatePackageConfig( + packageConfigFile, + generatedDirectory, + project.manifest.generateSyntheticPackage, + ); + if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { + final Directory exampleGeneratedDirectory = _fileSystem.directory( + _fileSystem.path.join(project.example.directory.path, '.dart_tool', 'flutter_gen')); + await _updatePackageConfig( + project.example.packageConfigFile, + exampleGeneratedDirectory, + project.example.manifest.generateSyntheticPackage, ); + } + } + + /// Runs pub with [arguments]. + /// + /// Retries the command as long as the exit code is + /// `_kPubExitCodeUnavailable`. + /// + /// Prints the stderr and stdout of the last run. + /// + /// Sends an analytics event + Future _runWithRetries( + List arguments, { + required String command, + required bool printProgress, + required PubContext context, + required bool retry, + required String directory, + String failureMessage = 'pub failed', + String? flutterRootOverride, + }) async { + int exitCode; + int attempts = 0; + int duration = 1; + + List<_OutputLine>? output; + StreamSubscription recordLines(Stream> stream, _OutputStream streamName) { + return stream + .transform(utf8.decoder) + .transform(const LineSplitter()) + .listen((String line) => output!.add(_OutputLine(line, streamName))); + } + + final Status? status = printProgress + ? _logger.startProgress('Running "flutter pub $command" in ${_fileSystem.path.basename(directory)}...',) + : null; + final List pubCommand = _pubCommand(arguments); + final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); + try { + do { + output = <_OutputLine>[]; + attempts += 1; + final io.Process process = await _processUtils.start( + pubCommand, + workingDirectory: _fileSystem.path.current, + environment: pubEnvironment, + ); + final StreamSubscription stdoutSubscription = + recordLines(process.stdout, _OutputStream.stdout); + final StreamSubscription stderrSubscription = + recordLines(process.stderr, _OutputStream.stderr); + + exitCode = await process.exitCode; + unawaited(stdoutSubscription.cancel()); + unawaited(stderrSubscription.cancel()); + + if (retry && exitCode == _kPubExitCodeUnavailable) { + _logger.printStatus( + '$failureMessage (server unavailable) -- attempting retry $attempts in $duration ' + 'second${ duration == 1 ? "" : "s"}...', + ); + await Future.delayed(Duration(seconds: duration)); + if (duration < 64) { + duration *= 2; + } + // This will cause a retry. + output = null; + } + } while (output == null); status?.stop(); // The exception is rethrown, so don't catch only Exceptions. } catch (exception) { // ignore: avoid_catches_without_on_clauses @@ -342,15 +431,45 @@ class _DefaultPub implements Pub { rethrow; } - if (!packageConfigFile.existsSync()) { - throwToolExit('$directory: pub did not create .dart_tools/package_config.json file.'); + if (printProgress) { + // Show the output of the last run. + for (final _OutputLine line in output) { + switch (line.stream) { + case _OutputStream.stdout: + _stdio.stdoutWrite('${line.line}\n'); + break; + case _OutputStream.stderr: + _stdio.stderrWrite('${line.line}\n'); + break; + } + } + } + + final int code = exitCode; + String result = 'success'; + if (output.any((_OutputLine line) => line.line.contains('version solving failed'))) { + result = 'version-solving-failed'; + } else if (code != 0) { + result = 'failure'; + } + PubResultEvent( + context: context.toAnalyticsString(), + result: result, + usage: _usage, + ).send(); + final String lastPubMessage = output.isEmpty ? 'no message' : output.last.line; + + if (code != 0) { + final StringBuffer buffer = StringBuffer('$failureMessage\n'); + buffer.writeln('command: "${pubCommand.join(' ')}"'); + buffer.write(_stringifyPubEnv(pubEnvironment)); + buffer.writeln('exit code: $code'); + buffer.writeln('last line of pub output: "${lastPubMessage.trim()}"'); + throwToolExit( + buffer.toString(), + exitCode: code, + ); } - lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig( - packageConfigFile, - generatedDirectory, - generateSyntheticPackage, - ); } // For surfacing pub env in crash reporting @@ -374,19 +493,13 @@ class _DefaultPub implements Pub { String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, String? flutterRootOverride, }) async { - showTraceForErrors ??= await _botDetector.isRunningOnBot; + final bool showTraceForErrors = await _botDetector.isRunningOnBot; String lastPubMessage = 'no message'; - bool versionSolvingFailed = false; String? filterWrapper(String line) { lastPubMessage = line; - if (line.contains('version solving failed')) { - versionSolvingFailed = true; - } if (filter == null) { return line; } @@ -396,44 +509,17 @@ class _DefaultPub implements Pub { if (showTraceForErrors) { arguments.insert(0, '--trace'); } - int attempts = 0; - int duration = 1; - int code; - final List pubCommand = _pubCommand(arguments); final Map pubEnvironment = await _createPubEnvironment(context, flutterRootOverride); - while (true) { - attempts += 1; - code = await _processUtils.stream( + final List pubCommand = _pubCommand(arguments); + final int code = await _processUtils.stream( pubCommand, workingDirectory: directory, mapFunction: filterWrapper, // may set versionSolvingFailed, lastPubMessage environment: pubEnvironment, ); - String? message; - if (retry) { - if (code == _kPubExitCodeUnavailable) { - message = 'server unavailable'; - } - } - if (message == null) { - break; - } - versionSolvingFailed = false; - _logger.printStatus( - '$failureMessage ($message) -- attempting retry $attempts in $duration ' - 'second${ duration == 1 ? "" : "s"}...', - ); - await Future.delayed(Duration(seconds: duration)); - if (duration < 64) { - duration *= 2; - } - } - assert(code != null); String result = 'success'; - if (versionSolvingFailed) { - result = 'version-solving-failed'; - } else if (code != 0) { + if (code != 0) { result = 'failure'; } PubResultEvent( @@ -465,7 +551,10 @@ class _DefaultPub implements Pub { }) async { // Fully resolved pub or pub.bat is calculated based on current platform. final io.Process process = await _processUtils.start( - _pubCommand(arguments), + _pubCommand([ + if (_logger.supportsColor) '--color', + ...arguments, + ]), workingDirectory: directory, environment: await _createPubEnvironment(PubContext.interactive), ); @@ -721,3 +810,14 @@ class _DefaultPub implements Pub { return buffer.toString(); } } + +class _OutputLine { + _OutputLine(this.line, this.stream); + final String line; + final _OutputStream stream; +} + +enum _OutputStream { + stdout, + stderr, +} diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 399aa46d72370..7099f1b8c1ae0 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -42,6 +42,7 @@ import 'web/chrome.dart'; import 'web/web_validator.dart'; import 'web/workflow.dart'; import 'windows/visual_studio_validator.dart'; +import 'windows/windows_version_validator.dart'; import 'windows/windows_workflow.dart'; abstract class DoctorValidatorsProvider { @@ -129,6 +130,10 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider { flutterRoot: () => Cache.flutterRoot!, operatingSystemUtils: globals.os, ), + if (platform.isWindows) + WindowsVersionValidator( + processManager: globals.processManager, + ), if (androidWorkflow!.appliesToHostPlatform) GroupedValidator([androidValidator!, androidLicenseValidator!]), if (globals.iosWorkflow!.appliesToHostPlatform || macOSWorkflow.appliesToHostPlatform) diff --git a/packages/flutter_tools/lib/src/flutter_cache.dart b/packages/flutter_tools/lib/src/flutter_cache.dart index 4ef0ef317de69..22609b8d8cd03 100644 --- a/packages/flutter_tools/lib/src/flutter_cache.dart +++ b/packages/flutter_tools/lib/src/flutter_cache.dart @@ -19,6 +19,7 @@ import 'cache.dart'; import 'dart/package_map.dart'; import 'dart/pub.dart'; import 'globals.dart' as globals; +import 'project.dart'; /// An implementation of the [Cache] which provides all of Flutter's default artifacts. class FlutterCache extends Cache { @@ -29,6 +30,7 @@ class FlutterCache extends Cache { required super.fileSystem, required Platform platform, required super.osUtils, + required FlutterProjectFactory projectFactory, }) : super(logger: logger, platform: platform, artifacts: []) { registerArtifact(MaterialFonts(this)); registerArtifact(GradleWrapper(this)); @@ -54,6 +56,7 @@ class FlutterCache extends Cache { // before the version is determined. flutterRoot: () => Cache.flutterRoot!, pub: () => pub, + projectFactory: projectFactory, )); } } @@ -70,14 +73,17 @@ class PubDependencies extends ArtifactSet { required String Function() flutterRoot, required Logger logger, required Pub Function() pub, + required FlutterProjectFactory projectFactory, }) : _logger = logger, _flutterRoot = flutterRoot, _pub = pub, + _projectFactory = projectFactory, super(DevelopmentArtifact.universal); final String Function() _flutterRoot; final Logger _logger; final Pub Function() _pub; + final FlutterProjectFactory _projectFactory; @override Future isUpToDate( @@ -118,7 +124,9 @@ class PubDependencies extends ArtifactSet { ) async { await _pub().get( context: PubContext.pubGet, - directory: fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools'), + project: _projectFactory.fromDirectory( + fileSystem.directory(fileSystem.path.join(_flutterRoot(), 'packages', 'flutter_tools')) + ), offline: offline ); } diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index de428242089a6..4b493d93c47b0 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -707,7 +707,7 @@ abstract class ResidentHandlers { } final List views = await device!.vmService!.getFlutterViews(); for (final FlutterView view in views) { - final Map? rasterData = + final Map? rasterData = await device.vmService!.renderFrameWithRasterStats( viewId: view.id, uiIsolateId: view.uiIsolate!.id, diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index e4e193db21562..41eee55e51e83 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1355,7 +1355,7 @@ abstract class FlutterCommand extends Command { await pub.get( context: PubContext.getVerifyContext(name), - generateSyntheticPackage: project.manifest.generateSyntheticPackage, + project: project, checkUpToDate: cachePubGet, ); await project.regeneratePlatformSpecificTooling(); diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index 1d1d5c7fc178e..95429336fe013 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart @@ -557,7 +557,7 @@ class FlutterVmService { /// for rasterization which is not reflective of how long the frame takes in /// production. This is primarily intended to be used to identify the layers /// that result in the most raster perf degradation. - Future?> renderFrameWithRasterStats({ + Future?> renderFrameWithRasterStats({ required String? viewId, required String? uiIsolateId, }) async { @@ -568,7 +568,7 @@ class FlutterVmService { 'viewId': viewId, }, ); - return response?.json as Map?; + return response?.json; } Future flutterDebugDumpApp({ diff --git a/packages/flutter_tools/lib/src/windows/windows_version_validator.dart b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart new file mode 100644 index 0000000000000..bc43193e3eace --- /dev/null +++ b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart @@ -0,0 +1,70 @@ +// 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:process/process.dart'; + +import '../base/io.dart'; +import '../doctor_validator.dart'; + +/// Flutter only supports development on Windows host machines version 10 and greater. +const List kUnsupportedVersions = [ + '6', + '7', + '8', +]; + +/// Regex pattern for identifying line from systeminfo stdout with windows version +/// (ie. 10.5.4123) +const String kWindowsOSVersionSemVerPattern = + r'^(OS Version:\s*)([0-9]+\.[0-9]+\.[0-9]+)(.*)$'; + +/// Validator for supported Windows host machine operating system version. +class WindowsVersionValidator extends DoctorValidator { + const WindowsVersionValidator({required ProcessManager processManager}) + : _processManager = processManager, + super('Windows Version'); + + final ProcessManager _processManager; + + @override + Future validate() async { + final ProcessResult result = + await _processManager.run(['systeminfo']); + + if (result.exitCode != 0) { + return const ValidationResult( + ValidationType.missing, + [], + statusInfo: 'Exit status from running `systeminfo` was unsuccessful', + ); + } + + final String resultStdout = result.stdout as String; + + final RegExp regex = + RegExp(kWindowsOSVersionSemVerPattern, multiLine: true); + final Iterable matches = regex.allMatches(resultStdout); + + // Use the string split method to extract the major version + // and check against the [kUnsupportedVersions] list + final ValidationType windowsVersionStatus; + final String statusInfo; + if (matches.length == 1 && + !kUnsupportedVersions + .contains(matches.elementAt(0).group(2)?.split('.').elementAt(0))) { + windowsVersionStatus = ValidationType.installed; + statusInfo = 'Installed version of Windows is version 10 or higher'; + } else { + windowsVersionStatus = ValidationType.missing; + statusInfo = + 'Unable to confirm if installed Windows version is 10 or greater'; + } + + return ValidationResult( + windowsVersionStatus, + const [], + statusInfo: statusInfo, + ); + } +} diff --git a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart index 2322d70d26a24..8ab74392f75dc 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart @@ -17,12 +17,14 @@ import 'package:flutter_tools/src/commands/analyze.dart'; import 'package:flutter_tools/src/dart/analysis.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project_validator.dart'; import 'package:process/process.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; +import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { @@ -36,6 +38,7 @@ void main() { late ProcessManager processManager; late AnsiTerminal terminal; late Logger logger; + late FakeStdio mockStdio; setUp(() { fileSystem = globals.localFileSystem; @@ -44,6 +47,7 @@ void main() { terminal = AnsiTerminal(platform: platform, stdio: Stdio()); logger = BufferLogger(outputPreferences: OutputPreferences.test(), terminal: terminal); tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analysis_test.'); + mockStdio = FakeStdio(); }); tearDown(() { @@ -80,10 +84,11 @@ void main() { platform: const LocalPlatform(), botDetector: globals.botDetector, usage: globals.flutterUsage, + stdio: mockStdio, ); await pub.get( context: PubContext.flutterTests, - directory: tempDir.path, + project: FlutterProject.fromDirectoryTest(tempDir), ); final AnalysisServer server = AnalysisServer( @@ -119,10 +124,11 @@ void main() { platform: const LocalPlatform(), usage: globals.flutterUsage, botDetector: globals.botDetector, + stdio: mockStdio, ); await pub.get( context: PubContext.flutterTests, - directory: tempDir.path, + project: FlutterProject.fromDirectoryTest(tempDir), ); final AnalysisServer server = AnalysisServer( diff --git a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart index 6cc52e3230972..86ebe770eaeed 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/create_usage_test.dart @@ -11,6 +11,7 @@ import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor_validator.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/project.dart'; import 'package:test/fake.dart'; import '../../src/context.dart'; @@ -27,17 +28,18 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fs.directory(directory).childFile('.packages').createSync(); + project.directory.childFile('.packages').createSync(); if (offline == true) { calledGetOffline += 1; } else { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index 397b4a666ce39..966d552503310 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -306,7 +306,7 @@ class FakePub extends Fake implements Pub { @override Future get({ PubContext? context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart index 080fa54e794a2..6861f22253cc3 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/pub_get_test.dart @@ -169,17 +169,18 @@ class FakePub extends Fake implements Pub { @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - fileSystem.directory(directory) + fileSystem.directory(project.directory) .childDirectory('.dart_tool') .childFile('package_config.json') ..createSync(recursive: true) diff --git a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart index 2d947bc5c1e1a..92d4f597c541b 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/update_packages_test.dart @@ -8,6 +8,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/update_packages.dart'; import 'package:flutter_tools/src/dart/pub.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:test/fake.dart'; import 'package:yaml/yaml.dart'; @@ -223,20 +224,19 @@ class FakePub extends Fake implements Pub { @override Future get({ required PubContext context, - String? directory, + required FlutterProject project, bool skipIfAbsent = false, bool upgrade = false, bool offline = false, bool generateSyntheticPackage = false, + bool generateSyntheticPackageForExample = false, String? flutterRootOverride, bool checkUpToDate = false, bool shouldSkipThirdPartyGenerator = true, bool printProgress = true, }) async { - if (directory != null) { - pubGetDirectories.add(directory); - } - fileSystem.directory(directory).childFile('pubspec.lock') + pubGetDirectories.add(project.directory.path); + project.directory.childFile('pubspec.lock') ..createSync(recursive: true) ..writeAsStringSync(''' # Generated by pub @@ -266,8 +266,6 @@ sdks: String? directory, MessageFilter? filter, String failureMessage = 'pub failed', - required bool retry, - bool? showTraceForErrors, }) async { if (directory != null) { pubBatchDirectories.add(directory); diff --git a/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart b/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart index b3d346dc1cbac..dceac215ebccb 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/build_aar_test.dart @@ -20,7 +20,7 @@ import '../../src/android_common.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; -import '../../src/fakes.dart'; +import '../../src/fakes.dart' hide FakeFlutterProjectFactory; import '../../src/test_flutter_command_runner.dart'; void main() { diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart index 47ef02afd8d11..8d9707c4e1d41 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart @@ -64,6 +64,7 @@ void main() { late LoggingProcessManager loggingProcessManager; late FakeProcessManager fakeProcessManager; late BufferLogger logger; + late FakeStdio mockStdio; setUpAll(() async { Cache.disableLocking(); @@ -80,6 +81,7 @@ void main() { channel: frameworkChannel, ); fakeProcessManager = FakeProcessManager.empty(); + mockStdio = FakeStdio(); }); tearDown(() { @@ -171,6 +173,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -218,6 +221,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -244,6 +248,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -273,6 +278,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -298,6 +304,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), ...noColorTerminalOverride, }); @@ -323,6 +330,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), ...noColorTerminalOverride, }); @@ -356,6 +364,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -388,6 +397,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -415,6 +425,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -453,6 +464,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -482,6 +494,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -520,6 +533,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -550,6 +564,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -580,6 +595,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), Logger: ()=>logger, }); @@ -607,6 +623,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -728,6 +745,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1426,6 +1444,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1454,6 +1473,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1711,6 +1731,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1735,6 +1756,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1885,6 +1907,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -1909,13 +1932,14 @@ void main() { }, overrides: { ProcessManager: () => loggingProcessManager, - Pub: () => Pub( + Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, processManager: globals.processManager, usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }, ); @@ -2869,6 +2893,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); diff --git a/packages/flutter_tools/test/commands.shard/permeable/format_test.dart b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart index 7a154bd0604c2..8180d2f7b9623 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/format_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/format_test.dart @@ -4,21 +4,25 @@ import 'package:args/command_runner.dart'; import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/format.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import '../../src/common.dart'; import '../../src/context.dart'; +import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { group('format', () { late Directory tempDir; + late FakeStdio mockStdio; setUp(() { Cache.disableLocking(); tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_format_test.'); + mockStdio = FakeStdio(); }); tearDown(() { @@ -38,6 +42,8 @@ void main() { final String formatted = srcFile.readAsStringSync(); expect(formatted, original); + }, overrides: { + Stdio: () => mockStdio, }); testUsingContext('dry-run', () async { diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index a145dd702724d..e6a98415bb0cd 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -30,6 +30,12 @@ import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { + late FakeStdio mockStdio; + + setUp(() { + mockStdio = FakeStdio()..stdout.terminalColumns = 80; + }); + Cache.disableLocking(); group('packages get/upgrade', () { late Directory tempDir; @@ -195,16 +201,25 @@ void main() { } } - testUsingContext('get fetches packages', () async { + testUsingContext('get fetches packages and has output from pub', () async { final String projectPath = await createProject(tempDir, arguments: ['--no-pub', '--template=module']); removeGeneratedFiles(projectPath); await runCommandIn(projectPath, 'get'); + expect(mockStdio.stdout.writes.map(utf8.decode), + allOf( + contains(matches(RegExp(r'Resolving dependencies in .+flutter_project\.\.\.'))), + contains('+ flutter 0.0.0 from sdk flutter\n'), + contains(matches(RegExp(r'Changed \d+ dependencies in .+flutter_project!'))), + ), + ); + expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -212,6 +227,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -225,6 +241,7 @@ void main() { expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -232,6 +249,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -245,6 +263,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesNumberPlugins, 0); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -252,6 +271,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -267,6 +287,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesNumberPlugins, 1); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -274,6 +295,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -287,6 +309,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesProjectModule, false); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -294,6 +317,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -307,6 +331,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesProjectModule, true); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -314,6 +339,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -336,6 +362,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v1'); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -343,6 +370,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -356,6 +384,7 @@ void main() { expect((await getCommand.usageValues).commandPackagesAndroidEmbeddingVersion, 'v2'); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -363,6 +392,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -376,7 +406,7 @@ void main() { expectDependenciesResolved(projectPath); expectZeroPluginsInjected(projectPath); }, overrides: { - Stdio: () => FakeStdio()..stdout.terminalColumns = 80, + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -384,6 +414,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -397,6 +428,7 @@ void main() { expectDependenciesResolved(projectPath); expectModulePluginInjected(projectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -404,6 +436,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -425,6 +458,7 @@ void main() { expectDependenciesResolved(exampleProjectPath); expectPluginInjected(exampleProjectPath); }, overrides: { + Stdio: () => mockStdio, Pub: () => Pub( fileSystem: globals.fs, logger: globals.logger, @@ -432,6 +466,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); }); @@ -468,6 +503,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -493,6 +529,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -523,6 +560,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -553,6 +591,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); @@ -581,6 +620,7 @@ void main() { usage: globals.flutterUsage, botDetector: globals.botDetector, platform: globals.platform, + stdio: mockStdio, ), }); }); diff --git a/packages/flutter_tools/test/general.shard/application_package_test.dart b/packages/flutter_tools/test/general.shard/application_package_test.dart index 5b94432d32cd9..fe1bb0fff416e 100644 --- a/packages/flutter_tools/test/general.shard/application_package_test.dart +++ b/packages/flutter_tools/test/general.shard/application_package_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/android/android_sdk.dart'; @@ -30,10 +28,10 @@ import '../src/fakes.dart'; void main() { group('Apk with partial Android SDK works', () { - FakeAndroidSdk sdk; - FakeProcessManager fakeProcessManager; - MemoryFileSystem fs; - Cache cache; + late FakeAndroidSdk sdk; + late FakeProcessManager fakeProcessManager; + late MemoryFileSystem fs; + late Cache cache; final Map overrides = { AndroidSdk: () => sdk, @@ -79,11 +77,10 @@ void main() { ) ); - final ApplicationPackage applicationPackage = await ApplicationPackageFactory.instance.getPackageForPlatform( + final ApplicationPackage applicationPackage = (await ApplicationPackageFactory.instance!.getPackageForPlatform( TargetPlatform.android_arm, - buildInfo: null, applicationBinary: apkFile, - ); + ))!; expect(applicationPackage.name, 'app.apk'); expect(applicationPackage, isA()); expect((applicationPackage as PrebuiltApplicationPackage).applicationPackage.path, apkFile.path); @@ -104,9 +101,8 @@ void main() { gradleWrapperDir.childFile('gradlew').writeAsStringSync('irrelevant'); gradleWrapperDir.childFile('gradlew.bat').writeAsStringSync('irrelevant'); - await ApplicationPackageFactory.instance.getPackageForPlatform( + await ApplicationPackageFactory.instance!.getPackageForPlatform( TargetPlatform.android_arm, - buildInfo: null, applicationBinary: globals.fs.file('app.apk'), ); expect(fakeProcessManager, hasNoRemainingExpectations); @@ -116,19 +112,16 @@ void main() { final AndroidSdkVersion sdkVersion = FakeAndroidSdkVersion(); sdk.latestVersion = sdkVersion; - await ApplicationPackageFactory.instance.getPackageForPlatform( + await ApplicationPackageFactory.instance!.getPackageForPlatform( TargetPlatform.android_arm, - buildInfo: null, ); expect(fakeProcessManager, hasNoRemainingExpectations); }, overrides: overrides); testWithoutContext('returns null when failed to extract manifest', () async { - final AndroidSdkVersion sdkVersion = FakeAndroidSdkVersion(); - sdk.latestVersion = sdkVersion; final Logger logger = BufferLogger.test(); - final AndroidApk androidApk = AndroidApk.fromApk( - null, + final AndroidApk? androidApk = AndroidApk.fromApk( + fs.file(''), processManager: fakeProcessManager, logger: logger, userMessages: UserMessages(), @@ -146,7 +139,7 @@ void main() { final ApkManifestData data = ApkManifestData.parseFromXmlDump( _aaptDataWithExplicitEnabledAndMainLauncherActivity, BufferLogger.test(), - ); + )!; expect(data, isNotNull); expect(data.packageName, 'io.flutter.examples.hello_world'); @@ -157,7 +150,7 @@ void main() { final ApkManifestData data = ApkManifestData.parseFromXmlDump( _aaptDataWithDefaultEnabledAndMainLauncherActivity, BufferLogger.test(), - ); + )!; expect(data, isNotNull); expect(data.packageName, 'io.flutter.examples.hello_world'); @@ -168,7 +161,7 @@ void main() { final ApkManifestData data = ApkManifestData.parseFromXmlDump( _aaptDataWithDistNamespace, BufferLogger.test(), - ); + )!; expect(data, isNotNull); expect(data.packageName, 'io.flutter.examples.hello_world'); @@ -177,7 +170,7 @@ void main() { testWithoutContext('Error when parsing manifest with no Activity that has enabled set to true nor has no value for its enabled field', () { final BufferLogger logger = BufferLogger.test(); - final ApkManifestData data = ApkManifestData.parseFromXmlDump( + final ApkManifestData? data = ApkManifestData.parseFromXmlDump( _aaptDataWithNoEnabledActivity, logger, ); @@ -191,7 +184,7 @@ void main() { testWithoutContext('Error when parsing manifest with no Activity that has action set to android.intent.action.MAIN', () { final BufferLogger logger = BufferLogger.test(); - final ApkManifestData data = ApkManifestData.parseFromXmlDump( + final ApkManifestData? data = ApkManifestData.parseFromXmlDump( _aaptDataWithNoMainActivity, logger, ); @@ -205,7 +198,7 @@ void main() { testWithoutContext('Error when parsing manifest with no Activity that has category set to android.intent.category.LAUNCHER', () { final BufferLogger logger = BufferLogger.test(); - final ApkManifestData data = ApkManifestData.parseFromXmlDump( + final ApkManifestData? data = ApkManifestData.parseFromXmlDump( _aaptDataWithNoLauncherActivity, logger, ); @@ -221,7 +214,7 @@ void main() { final ApkManifestData data = ApkManifestData.parseFromXmlDump( _aaptDataWithLauncherAndDefaultActivity, BufferLogger.test(), - ); + )!; expect(data, isNotNull); expect(data.packageName, 'io.flutter.examples.hello_world'); @@ -229,7 +222,7 @@ void main() { }); testWithoutContext('Parses manifest with missing application tag', () async { - final ApkManifestData data = ApkManifestData.parseFromXmlDump( + final ApkManifestData? data = ApkManifestData.parseFromXmlDump( _aaptDataWithoutApplication, BufferLogger.test(), ); @@ -239,8 +232,8 @@ void main() { }); group('PrebuiltIOSApp', () { - FakeOperatingSystemUtils os; - FakePlistParser testPlistParser; + late FakeOperatingSystemUtils os; + late FakePlistParser testPlistParser; final Map overrides = { FileSystem: () => MemoryFileSystem.test(), @@ -255,8 +248,8 @@ void main() { }); testUsingContext('Error on non-existing file', () { - final PrebuiltIOSApp iosApp = - IOSApp.fromPrebuiltApp(globals.fs.file('not_existing.ipa')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = + IOSApp.fromPrebuiltApp(globals.fs.file('not_existing.ipa')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect( testLogger.errorText, @@ -266,8 +259,8 @@ void main() { testUsingContext('Error on non-app-bundle folder', () { globals.fs.directory('regular_folder').createSync(); - final PrebuiltIOSApp iosApp = - IOSApp.fromPrebuiltApp(globals.fs.file('regular_folder')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = + IOSApp.fromPrebuiltApp(globals.fs.file('regular_folder')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect( testLogger.errorText, 'Folder "regular_folder" is not an app bundle.\n'); @@ -275,7 +268,7 @@ void main() { testUsingContext('Error on no info.plist', () { globals.fs.directory('bundle.app').createSync(); - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect( testLogger.errorText, @@ -286,7 +279,7 @@ void main() { testUsingContext('Error on bad info.plist', () { globals.fs.directory('bundle.app').createSync(); globals.fs.file('bundle.app/Info.plist').createSync(); - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect( testLogger.errorText, @@ -299,7 +292,7 @@ void main() { globals.fs.directory('bundle.app').createSync(); globals.fs.file('bundle.app/Info.plist').createSync(); testPlistParser.setProperty('CFBundleIdentifier', 'fooBundleId'); - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp; + final PrebuiltIOSApp iosApp = (IOSApp.fromPrebuiltApp(globals.fs.file('bundle.app')) as PrebuiltIOSApp?)!; expect(testLogger.errorText, isEmpty); expect(iosApp.uncompressedBundle.path, 'bundle.app'); expect(iosApp.id, 'fooBundleId'); @@ -309,7 +302,7 @@ void main() { testUsingContext('Bad ipa zip-file, no payload dir', () { globals.fs.file('app.ipa').createSync(); - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect( testLogger.errorText, @@ -330,7 +323,7 @@ void main() { globals.fs.directory(bundlePath1).createSync(recursive: true); globals.fs.directory(bundlePath2).createSync(recursive: true); }; - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp; + final PrebuiltIOSApp? iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp?; expect(iosApp, isNull); expect(testLogger.errorText, 'Invalid prebuilt iOS ipa. Does not contain a single app bundle.\n'); @@ -350,7 +343,7 @@ void main() { .file(globals.fs.path.join(bundleAppDir.path, 'Info.plist')) .createSync(); }; - final PrebuiltIOSApp iosApp = IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp; + final PrebuiltIOSApp iosApp = (IOSApp.fromPrebuiltApp(globals.fs.file('app.ipa')) as PrebuiltIOSApp?)!; expect(testLogger.errorText, isEmpty); expect(iosApp.uncompressedBundle.path, endsWith('bundle.app')); expect(iosApp.id, 'fooBundleId'); @@ -361,8 +354,8 @@ void main() { testUsingContext('returns null when there is no ios or .ios directory', () async { globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final BuildableIOSApp iosApp = await IOSApp.fromIosProject( - FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp; + final BuildableIOSApp? iosApp = await IOSApp.fromIosProject( + FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp?; expect(iosApp, null); }, overrides: overrides); @@ -371,8 +364,8 @@ void main() { globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); globals.fs.file('ios/FooBar.xcodeproj').createSync(recursive: true); - final BuildableIOSApp iosApp = await IOSApp.fromIosProject( - FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp; + final BuildableIOSApp? iosApp = await IOSApp.fromIosProject( + FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp?; expect(iosApp, null); }, overrides: overrides); @@ -381,8 +374,8 @@ void main() { globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); globals.fs.file('ios/Runner.xcodeproj').createSync(recursive: true); - final BuildableIOSApp iosApp = await IOSApp.fromIosProject( - FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp; + final BuildableIOSApp? iosApp = await IOSApp.fromIosProject( + FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp?; expect(iosApp, null); }, overrides: overrides); @@ -392,8 +385,8 @@ void main() { globals.fs.file('.packages').createSync(); final Directory project = globals.fs.directory('ios/Runner.xcodeproj')..createSync(recursive: true); project.childFile('project.pbxproj').createSync(); - final BuildableIOSApp iosApp = await IOSApp.fromIosProject( - FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp; + final BuildableIOSApp? iosApp = await IOSApp.fromIosProject( + FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp?; expect(iosApp, null); }, overrides: overrides); @@ -407,8 +400,8 @@ void main() { }; testUsingContext('Error on non-existing file', () { - final PrebuiltFuchsiaApp fuchsiaApp = - FuchsiaApp.fromPrebuiltApp(globals.fs.file('not_existing.far')) as PrebuiltFuchsiaApp; + final PrebuiltFuchsiaApp? fuchsiaApp = + FuchsiaApp.fromPrebuiltApp(globals.fs.file('not_existing.far')) as PrebuiltFuchsiaApp?; expect(fuchsiaApp, isNull); expect( testLogger.errorText, @@ -418,8 +411,8 @@ void main() { testUsingContext('Error on non-far file', () { globals.fs.directory('regular_folder').createSync(); - final PrebuiltFuchsiaApp fuchsiaApp = - FuchsiaApp.fromPrebuiltApp(globals.fs.file('regular_folder')) as PrebuiltFuchsiaApp; + final PrebuiltFuchsiaApp? fuchsiaApp = + FuchsiaApp.fromPrebuiltApp(globals.fs.file('regular_folder')) as PrebuiltFuchsiaApp?; expect(fuchsiaApp, isNull); expect( testLogger.errorText, @@ -429,7 +422,7 @@ void main() { testUsingContext('Success with far file', () { globals.fs.file('bundle.far').createSync(); - final PrebuiltFuchsiaApp fuchsiaApp = FuchsiaApp.fromPrebuiltApp(globals.fs.file('bundle.far')) as PrebuiltFuchsiaApp; + final PrebuiltFuchsiaApp fuchsiaApp = (FuchsiaApp.fromPrebuiltApp(globals.fs.file('bundle.far')) as PrebuiltFuchsiaApp?)!; expect(testLogger.errorText, isEmpty); expect(fuchsiaApp.id, 'bundle.far'); expect(fuchsiaApp.applicationPackage.path, globals.fs.file('bundle.far').path); @@ -438,7 +431,7 @@ void main() { testUsingContext('returns null when there is no fuchsia', () async { globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final BuildableFuchsiaApp fuchsiaApp = FuchsiaApp.fromFuchsiaProject(FlutterProject.fromDirectory(globals.fs.currentDirectory).fuchsia) as BuildableFuchsiaApp; + final BuildableFuchsiaApp? fuchsiaApp = FuchsiaApp.fromFuchsiaProject(FlutterProject.fromDirectory(globals.fs.currentDirectory).fuchsia) as BuildableFuchsiaApp?; expect(fuchsiaApp, null); }, overrides: overrides); @@ -707,7 +700,7 @@ N: android=http://schemas.android.com/apk/res/android '''; class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils { - void Function(File, Directory) onUnzip; + void Function(File, Directory)? onUnzip; @override void unzip(File file, Directory targetDirectory) { @@ -717,16 +710,16 @@ class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils { class FakeAndroidSdk extends Fake implements AndroidSdk { @override - bool platformToolsAvailable; + late bool platformToolsAvailable; @override - bool licensesAvailable; + late bool licensesAvailable; @override - AndroidSdkVersion latestVersion; + AndroidSdkVersion? latestVersion; } class FakeAndroidSdkVersion extends Fake implements AndroidSdkVersion { @override - String aaptPath; + late String aaptPath; } diff --git a/packages/flutter_tools/test/general.shard/args_test.dart b/packages/flutter_tools/test/general.shard/args_test.dart index 4725e37d2aa65..683a4df708811 100644 --- a/packages/flutter_tools/test/general.shard/args_test.dart +++ b/packages/flutter_tools/test/general.shard/args_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:flutter_tools/executable.dart' as executable; @@ -111,7 +109,7 @@ void main() { }); } -void verifyCommandRunner(CommandRunner runner) { +void verifyCommandRunner(CommandRunner runner) { expect(runner.argParser, isNotNull, reason: '${runner.runtimeType} has no argParser'); expect(runner.argParser.allowsAnything, isFalse, reason: '${runner.runtimeType} allows anything'); expect(runner.argParser.allowTrailingOptions, isFalse, reason: '${runner.runtimeType} allows trailing options'); @@ -119,7 +117,7 @@ void verifyCommandRunner(CommandRunner runner) { runner.commands.values.forEach(verifyCommand); } -void verifyCommand(Command runner) { +void verifyCommand(Command runner) { expect(runner.argParser, isNotNull, reason: 'command ${runner.name} has no argParser'); verifyOptions(runner.name, runner.argParser.options.values); @@ -161,7 +159,7 @@ const String _needHelp = "Every option must have help explaining what it does, e const String _header = ' Comment: '; -void verifyOptions(String command, Iterable