From 9207b85de88db4ca78599c0ca82c0b3420e0c9a9 Mon Sep 17 00:00:00 2001 From: Flutter GitHub Bot Date: Mon, 29 Jan 2024 17:16:06 -0500 Subject: [PATCH 01/16] Marks Mac_pixel_7pro native_assets_android to be unflaky (#141675) The test has been passing for [50 consecutive runs](https://data.corp.google.com/sites/flutter_infra_metrics_datasite/flutter_check_test_flakiness_status_dashboard/?p=BUILDER_NAME:%22Mac_pixel_7pro%20native_assets_android%22). This test can be marked as unflaky. --- .ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci.yaml b/.ci.yaml index 1c111e1679e7..d26468d19d65 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -4156,7 +4156,6 @@ targets: - name: Mac_pixel_7pro native_assets_android recipe: devicelab/devicelab_drone presubmit: false - bringup: true timeout: 60 properties: tags: > From 995e3fad7c9f6130e250f7f64ac922a5317f342d Mon Sep 17 00:00:00 2001 From: Camille Simon <43054281+camsim99@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:44:24 -0800 Subject: [PATCH 02/16] Revert "Reland: "Fix how Gradle resolves Android plugin" (#137115)" (#142464) This reverts commit f5ac225c8da7a73ca16801054b8d4901d556b0fd, i.e. https://github.com/flutter/flutter/pull/137115. This is a continuation of https://github.com/flutter/flutter/pull/142266 that was redone based on feedback to make this easier to revert in the future. The exact steps I took to create this revert: 1. Revert commit noted above 2. Fix merge conflicts, that notably involved reverting some changes in https://github.com/flutter/flutter/pull/140744 ~and https://github.com/flutter/flutter/pull/141417~ (fixed my merge to avoid the second PR from being affected) 3. Delete `packages/flutter_tools/test/integration.shard/android_plugin_skip_unsupported_test.dart` as this was added in the commit noted above cc @Gustl22 since I couldn't tag as a reviewer --- .../gradle/module_plugin_loader.gradle | 39 +++- .../src/main/groovy/app_plugin_loader.groovy | 38 ++-- .../gradle/src/main/groovy/flutter.groovy | 210 +++++++----------- .../main/groovy/native_plugin_loader.groovy | 120 ---------- .../android_plugin_skip_unsupported_test.dart | 208 ----------------- .../plugin_each_settings_gradle_project.dart | 60 ----- .../test_data/plugin_project.dart | 99 --------- 7 files changed, 128 insertions(+), 646 deletions(-) delete mode 100644 packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy delete mode 100644 packages/flutter_tools/test/integration.shard/android_plugin_skip_unsupported_test.dart delete mode 100644 packages/flutter_tools/test/integration.shard/test_data/plugin_each_settings_gradle_project.dart delete mode 100644 packages/flutter_tools/test/integration.shard/test_data/plugin_project.dart diff --git a/packages/flutter_tools/gradle/module_plugin_loader.gradle b/packages/flutter_tools/gradle/module_plugin_loader.gradle index 6e52b5ae9bf6..2e3a80091499 100644 --- a/packages/flutter_tools/gradle/module_plugin_loader.gradle +++ b/packages/flutter_tools/gradle/module_plugin_loader.gradle @@ -5,26 +5,41 @@ // This file is included from `/.android/include_flutter.groovy`, // so it can be versioned with the Flutter SDK. -import java.nio.file.Paths - -File pathToThisDirectory = buildscript.sourceFile.parentFile -apply from: Paths.get(pathToThisDirectory.absolutePath, "src", "main", "groovy", "native_plugin_loader.groovy") +import groovy.json.JsonSlurper def moduleProjectRoot = project(':flutter').projectDir.parentFile.parentFile -List> nativePlugins = nativePluginLoader.getPlugins(moduleProjectRoot) -nativePlugins.each { androidPlugin -> - def pluginDirectory = new File(androidPlugin.path as String, 'android') - assert pluginDirectory.exists() - include ":${androidPlugin.name}" - project(":${androidPlugin.name}").projectDir = pluginDirectory +def object = null; +String flutterModulePath = project(':flutter').projectDir.parentFile.getAbsolutePath() +// If this logic is changed, also change the logic in app_plugin_loader.gradle. +def pluginsFile = new File(moduleProjectRoot, '.flutter-plugins-dependencies') +if (pluginsFile.exists()) { + object = new JsonSlurper().parseText(pluginsFile.text) + assert object instanceof Map + assert object.plugins instanceof Map + assert object.plugins.android instanceof List + // Includes the Flutter plugins that support the Android platform. + object.plugins.android.each { androidPlugin -> + assert androidPlugin.name instanceof String + assert androidPlugin.path instanceof String + // Skip plugins that have no native build (such as a Dart-only + // implementation of a federated plugin). + def needsBuild = androidPlugin.containsKey('native_build') ? androidPlugin['native_build'] : true + if (!needsBuild) { + return + } + def pluginDirectory = new File(androidPlugin.path, 'android') + assert pluginDirectory.exists() + include ":${androidPlugin.name}" + project(":${androidPlugin.name}").projectDir = pluginDirectory + } } -String flutterModulePath = project(':flutter').projectDir.parentFile.getAbsolutePath() gradle.getGradle().projectsLoaded { g -> g.rootProject.beforeEvaluate { p -> p.subprojects { subproject -> - if (nativePlugins.name.contains(subproject.name)) { + if (object != null && object.plugins != null && object.plugins.android != null + && object.plugins.android.name.contains(subproject.name)) { File androidPluginBuildOutputDir = new File(flutterModulePath + File.separator + "plugins_build_output" + File.separator + subproject.name); if (!androidPluginBuildOutputDir.exists()) { diff --git a/packages/flutter_tools/gradle/src/main/groovy/app_plugin_loader.groovy b/packages/flutter_tools/gradle/src/main/groovy/app_plugin_loader.groovy index 16965213df0f..402ab64e6227 100644 --- a/packages/flutter_tools/gradle/src/main/groovy/app_plugin_loader.groovy +++ b/packages/flutter_tools/gradle/src/main/groovy/app_plugin_loader.groovy @@ -1,29 +1,39 @@ +import groovy.json.JsonSlurper import org.gradle.api.Plugin import org.gradle.api.initialization.Settings -import java.nio.file.Paths - apply plugin: FlutterAppPluginLoaderPlugin class FlutterAppPluginLoaderPlugin implements Plugin { + // This string must match _kFlutterPluginsHasNativeBuildKey defined in + // packages/flutter_tools/lib/src/flutter_plugins.dart. + private final String nativeBuildKey = 'native_build' + @Override void apply(Settings settings) { def flutterProjectRoot = settings.settingsDir.parentFile - if(!settings.ext.hasProperty('flutterSdkPath')) { - def properties = new Properties() - def localPropertiesFile = new File(settings.rootProject.projectDir, "local.properties") - localPropertiesFile.withInputStream { properties.load(it) } - settings.ext.flutterSdkPath = properties.getProperty("flutter.sdk") - assert settings.ext.flutterSdkPath != null, "flutter.sdk not set in local.properties" + // If this logic is changed, also change the logic in module_plugin_loader.gradle. + def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins-dependencies') + if (!pluginsFile.exists()) { + return } - - // Load shared gradle functions - settings.apply from: Paths.get(settings.ext.flutterSdkPath, "packages", "flutter_tools", "gradle", "src", "main", "groovy", "native_plugin_loader.groovy") - List> nativePlugins = settings.ext.nativePluginLoader.getPlugins(flutterProjectRoot) - nativePlugins.each { androidPlugin -> - def pluginDirectory = new File(androidPlugin.path as String, 'android') + def object = new JsonSlurper().parseText(pluginsFile.text) + assert object instanceof Map + assert object.plugins instanceof Map + assert object.plugins.android instanceof List + // Includes the Flutter plugins that support the Android platform. + object.plugins.android.each { androidPlugin -> + assert androidPlugin.name instanceof String + assert androidPlugin.path instanceof String + // Skip plugins that have no native build (such as a Dart-only implementation + // of a federated plugin). + def needsBuild = androidPlugin.containsKey(nativeBuildKey) ? androidPlugin[nativeBuildKey] : true + if (!needsBuild) { + return + } + def pluginDirectory = new File(androidPlugin.path, 'android') assert pluginDirectory.exists() settings.include(":${androidPlugin.name}") settings.project(":${androidPlugin.name}").projectDir = pluginDirectory diff --git a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy index fdf73007f88b..afca2bbc2f50 100644 --- a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy +++ b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy @@ -4,6 +4,7 @@ // found in the LICENSE file. import com.android.build.OutputFile +import groovy.json.JsonSlurper import groovy.json.JsonGenerator import groovy.xml.QName import java.nio.file.Paths @@ -66,7 +67,7 @@ class FlutterExtension { * Specifies the relative directory to the Flutter project directory. * In an app project, this is ../.. since the app's Gradle build file is under android/app. */ - String source = "../.." + String source /** Allows to override the target file. Otherwise, the target is lib/main.dart. */ String target @@ -256,9 +257,6 @@ class FlutterPlugin implements Plugin { } } - // Load shared gradle functions - project.apply from: Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools", "gradle", "src", "main", "groovy", "native_plugin_loader.groovy") - FlutterExtension extension = project.extensions.create("flutter", FlutterExtension) Properties localProperties = new Properties() File localPropertiesFile = rootProject.file("local.properties") @@ -600,7 +598,7 @@ class FlutterPlugin implements Plugin { // This prevents duplicated classes when using custom build types. That is, a custom build // type like profile is used, and the plugin and app projects have API dependencies on the // embedding. - if (!isFlutterAppProject() || getPluginList(project).size() == 0) { + if (!isFlutterAppProject() || getPluginList().size() == 0) { addApiDependencies(project, buildType.name, "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion") } @@ -622,104 +620,19 @@ class FlutterPlugin implements Plugin { * Configures the Flutter plugin dependencies. * * The plugins are added to pubspec.yaml. Then, upon running `flutter pub get`, - * the tool generates a `.flutter-plugins-dependencies` file, which contains a map to each plugin location. + * the tool generates a `.flutter-plugins` file, which contains a 1:1 map to each plugin location. * Finally, the project's `settings.gradle` loads each plugin's android directory as a subproject. */ - private void configurePlugins(Project project) { - configureLegacyPluginEachProjects(project) - getPluginList(project).each(this.&configurePluginProject) - getPluginList(project).each(this.&configurePluginDependencies) - } - - // TODO(54566, 48918): Can remove once the issues are resolved. - // This means all references to `.flutter-plugins` are then removed and - // apps only depend exclusively on the `plugins` property in `.flutter-plugins-dependencies`. - /** - * Workaround to load non-native plugins for developers who may still use an - * old `settings.gradle` which includes all the plugins from the - * `.flutter-plugins` file, even if not made for Android. - * The settings.gradle then: - * 1) tries to add the android plugin implementation, which does not - * exist at all, but is also not included successfully - * (which does not throw an error and therefore isn't a problem), or - * 2) includes the plugin successfully as a valid android plugin - * directory exists, even if the surrounding flutter package does not - * support the android platform (see e.g. apple_maps_flutter: 1.0.1). - * So as it's included successfully it expects to be added as API. - * This is only possible by taking all plugins into account, which - * only appear on the `dependencyGraph` and in the `.flutter-plugins` file. - * So in summary the plugins are currently selected from the `dependencyGraph` - * and filtered then with the [doesSupportAndroidPlatform] method instead of - * just using the `plugins.android` list. - */ - private void configureLegacyPluginEachProjects(Project project) { - try { - if (!settingsGradleFile(project).text.contains("'.flutter-plugins'")) { - return - } - } catch (FileNotFoundException ignored) { - throw new GradleException("settings.gradle/settings.gradle.kts does not exist: ${settingsGradleFile(project).absolutePath}") - } - List> deps = getPluginDependencies(project) - List plugins = getPluginList(project).collect { it.name as String } - deps.removeIf { plugins.contains(it.name) } - deps.each { - Project pluginProject = project.rootProject.findProject(":${it.name}") - if (pluginProject == null) { - // Plugin was not included in `settings.gradle`, but is listed in `.flutter-plugins`. - project.logger.error("Plugin project :${it.name} listed, but not found. Please fix your settings.gradle/settings.gradle.kts.") - } else if (doesSupportAndroidPlatform(pluginProject.projectDir.parentFile.path as String)) { - // Plugin has a functioning `android` folder and is included successfully, although it's not supported. - // It must be configured nonetheless, to not throw an "Unresolved reference" exception. - configurePluginProject(it) - /* groovylint-disable-next-line EmptyElseBlock */ - } else { - // Plugin has no or an empty `android` folder. No action required. - } - } - } - - // TODO(54566): Can remove this function and its call sites once resolved. - /** - * Returns `true` if the given path contains an `android` directory - * containing a `build.gradle` or `build.gradle.kts` file. - */ - private Boolean doesSupportAndroidPlatform(String path) { - File buildGradle = new File(path, 'android' + File.separator + 'build.gradle') - File buildGradleKts = new File(path, 'android' + File.separator + 'build.gradle.kts') - if (buildGradle.exists() && buildGradleKts.exists()) { - project.logger.error( - "Both build.gradle and build.gradle.kts exist, so " + - "build.gradle.kts is ignored. This is likely a mistake." - ) - } - - return buildGradle.exists() || buildGradleKts.exists() - } - - /** - * Returns the Gradle settings script for the build. When both Groovy and - * Kotlin variants exist, then Groovy (settings.gradle) is preferred over - * Kotlin (settings.gradle.kts). This is the same behavior as Gradle 8.5. - */ - private File settingsGradleFile(Project project) { - File settingsGradle = new File(project.projectDir.parentFile, "settings.gradle") - File settingsGradleKts = new File(project.projectDir.parentFile, "settings.gradle.kts") - if (settingsGradle.exists() && settingsGradleKts.exists()) { - project.logger.error( - "Both settings.gradle and settings.gradle.kts exist, so " + - "settings.gradle.kts is ignored. This is likely a mistake." - ) - } - - return settingsGradle.exists() ? settingsGradle : settingsGradleKts + private void configurePlugins() { + getPluginList().each(this.&configurePluginProject) + getPluginDependencies().each(this.&configurePluginDependencies) } /** Adds the plugin project dependency to the app project. */ - private void configurePluginProject(Map pluginObject) { - assert(pluginObject.name instanceof String) - Project pluginProject = project.rootProject.findProject(":${pluginObject.name}") + private void configurePluginProject(String pluginName, String _) { + Project pluginProject = project.rootProject.findProject(":$pluginName") if (pluginProject == null) { + project.logger.error("Plugin project :$pluginName not found. Please update settings.gradle.") return } // Add plugin dependency to the app project. @@ -758,7 +671,7 @@ class FlutterPlugin implements Plugin { pluginProject.afterEvaluate { // Checks if there is a mismatch between the plugin compileSdkVersion and the project compileSdkVersion. if (pluginProject.android.compileSdkVersion > project.android.compileSdkVersion) { - project.logger.quiet("Warning: The plugin ${pluginObject.name} requires Android SDK version ${getCompileSdkFromProject(pluginProject)} or higher.") + project.logger.quiet("Warning: The plugin ${pluginName} requires Android SDK version ${getCompileSdkFromProject(pluginProject)} or higher.") project.logger.quiet("For more information about build configuration, see $kWebsiteDeploymentAndroidBuildConfig.") } @@ -811,14 +724,10 @@ class FlutterPlugin implements Plugin { String ndkVersionIfUnspecified = "21.1.6352462" /* The default for AGP 4.1.0 used in old templates. */ String projectNdkVersion = project.android.ndkVersion ?: ndkVersionIfUnspecified String maxPluginNdkVersion = projectNdkVersion - int numProcessedPlugins = getPluginList(project).size() + int numProcessedPlugins = getPluginList().size() - getPluginList(project).each { pluginObject -> - assert(pluginObject.name instanceof String) - Project pluginProject = project.rootProject.findProject(":${pluginObject.name}") - if (pluginProject == null) { - return - } + getPluginList().each { plugin -> + Project pluginProject = project.rootProject.findProject(plugin.key) pluginProject.afterEvaluate { // Default to int min if using a preview version to skip the sdk check. int pluginCompileSdkVersion = Integer.MIN_VALUE @@ -852,25 +761,35 @@ class FlutterPlugin implements Plugin { return gradleProject.android.compileSdkVersion.substring(8) } + /** + * Returns `true` if the given path contains an `android/build.gradle` file. + */ + private Boolean doesSupportAndroidPlatform(String path) { + File editableAndroidProject = new File(path, 'android' + File.separator + 'build.gradle') + return editableAndroidProject.exists() + } + /** * Add the dependencies on other plugin projects to the plugin project. * A plugin A can depend on plugin B. As a result, this dependency must be surfaced by * making the Gradle plugin project A depend on the Gradle plugin project B. */ - private void configurePluginDependencies(Map pluginObject) { - assert(pluginObject.name instanceof String) - Project pluginProject = project.rootProject.findProject(":${pluginObject.name}") - if (pluginProject == null) { + private void configurePluginDependencies(Object dependencyObject) { + assert(dependencyObject.name instanceof String) + Project pluginProject = project.rootProject.findProject(":${dependencyObject.name}") + if (pluginProject == null || + !doesSupportAndroidPlatform(pluginProject.projectDir.parentFile.path)) { return } - def dependencies = pluginObject.dependencies - assert(dependencies instanceof List) - dependencies.each { pluginDependencyName -> + assert(dependencyObject.dependencies instanceof List) + dependencyObject.dependencies.each { pluginDependencyName -> + assert(pluginDependencyName instanceof String) if (pluginDependencyName.empty) { return } Project dependencyProject = project.rootProject.findProject(":$pluginDependencyName") - if (dependencyProject == null) { + if (dependencyProject == null || + !doesSupportAndroidPlatform(dependencyProject.projectDir.parentFile.path)) { return } // Wait for the Android plugin to load and add the dependency to the plugin project. @@ -882,27 +801,52 @@ class FlutterPlugin implements Plugin { } } - /** - * Gets the list of plugins (as map) that support the Android platform. - * - * The map value contains either the plugins `name` (String), - * its `path` (String), or its `dependencies` (List). - * See [NativePluginLoader#getPlugins] in packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy - */ - private List> getPluginList(Project project) { - return project.ext.nativePluginLoader.getPlugins(getFlutterSourceDirectory()) + private Properties getPluginList() { + File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins') + Properties allPlugins = readPropertiesIfExist(pluginsFile) + Properties androidPlugins = new Properties() + allPlugins.each { name, path -> + if (doesSupportAndroidPlatform(path)) { + androidPlugins.setProperty(name, path) + } + // TODO(amirh): log an error if this plugin was specified to be an Android + // plugin according to the new schema, and was missing a build.gradle file. + // https://github.com/flutter/flutter/issues/40784 + } + return androidPlugins } - // TODO(54566, 48918): Remove in favor of [getPluginList] only, see also - // https://github.com/flutter/flutter/blob/1c90ed8b64d9ed8ce2431afad8bc6e6d9acc4556/packages/flutter_tools/lib/src/flutter_plugins.dart#L212 /** Gets the plugins dependencies from `.flutter-plugins-dependencies`. */ - private List> getPluginDependencies(Project project) { - Map meta = project.ext.nativePluginLoader.getDependenciesMetadata(getFlutterSourceDirectory()) - if (meta == null) { - return [] - } - assert(meta.dependencyGraph instanceof List) - return meta.dependencyGraph as List> + private List getPluginDependencies() { + // Consider a `.flutter-plugins-dependencies` file with the following content: + // { + // "dependencyGraph": [ + // { + // "name": "plugin-a", + // "dependencies": ["plugin-b","plugin-c"] + // }, + // { + // "name": "plugin-b", + // "dependencies": ["plugin-c"] + // }, + // { + // "name": "plugin-c", + // "dependencies": []' + // } + // ] + // } + // + // This means, `plugin-a` depends on `plugin-b` and `plugin-c`. + // `plugin-b` depends on `plugin-c`. + // `plugin-c` doesn't depend on anything. + File pluginsDependencyFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins-dependencies') + if (pluginsDependencyFile.exists()) { + def object = new JsonSlurper().parseText(pluginsDependencyFile.text) + assert(object instanceof Map) + assert(object.dependencyGraph instanceof List) + return object.dependencyGraph + } + return [] } private String resolveProperty(String name, String defaultValue) { @@ -1342,7 +1286,7 @@ class FlutterPlugin implements Plugin { String nativeAssetsDir = "${project.buildDir}/../native_assets/android/jniLibs/lib/" project.android.sourceSets.main.jniLibs.srcDir(nativeAssetsDir) } - configurePlugins(project) + configurePlugins() detectLowCompileSdkVersionOrNdkVersion() return } @@ -1394,7 +1338,7 @@ class FlutterPlugin implements Plugin { } } } - configurePlugins(project) + configurePlugins() detectLowCompileSdkVersionOrNdkVersion() } diff --git a/packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy b/packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy deleted file mode 100644 index f9eb7bba1952..000000000000 --- a/packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy +++ /dev/null @@ -1,120 +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 groovy.json.JsonSlurper - -@Singleton -class NativePluginLoader { - - // This string must match _kFlutterPluginsHasNativeBuildKey defined in - // packages/flutter_tools/lib/src/flutter_plugins.dart. - static final String nativeBuildKey = "native_build" - static final String flutterPluginsDependenciesFile = ".flutter-plugins-dependencies" - - /** - * Gets the list of plugins that support the Android platform. - * The list contains map elements with the following content: - * { - * "name": "plugin-a", - * "path": "/path/to/plugin-a", - * "dependencies": ["plugin-b", "plugin-c"], - * "native_build": true - * } - * - * Therefore the map value can either be a `String`, a `List` or a `boolean`. - */ - List> getPlugins(File flutterSourceDirectory) { - List> nativePlugins = [] - def meta = getDependenciesMetadata(flutterSourceDirectory) - if (meta == null) { - return nativePlugins - } - - assert(meta.plugins instanceof Map) - def androidPlugins = meta.plugins.android - assert(androidPlugins instanceof List) - // Includes the Flutter plugins that support the Android platform. - androidPlugins.each { Map androidPlugin -> - // The property types can be found in _filterPluginsByPlatform defined in - // packages/flutter_tools/lib/src/flutter_plugins.dart. - assert(androidPlugin.name instanceof String) - assert(androidPlugin.path instanceof String) - assert(androidPlugin.dependencies instanceof List) - // Skip plugins that have no native build (such as a Dart-only implementation - // of a federated plugin). - def needsBuild = androidPlugin.containsKey(nativeBuildKey) ? androidPlugin[nativeBuildKey] : true - if (needsBuild) { - nativePlugins.add(androidPlugin) - } - } - return nativePlugins - } - - - private Map parsedFlutterPluginsDependencies - - /** - * Parses /.flutter-plugins-dependencies - */ - Map getDependenciesMetadata(File flutterSourceDirectory) { - // Consider a `.flutter-plugins-dependencies` file with the following content: - // { - // "plugins": { - // "android": [ - // { - // "name": "plugin-a", - // "path": "/path/to/plugin-a", - // "dependencies": ["plugin-b", "plugin-c"], - // "native_build": true - // }, - // { - // "name": "plugin-b", - // "path": "/path/to/plugin-b", - // "dependencies": ["plugin-c"], - // "native_build": true - // }, - // { - // "name": "plugin-c", - // "path": "/path/to/plugin-c", - // "dependencies": [], - // "native_build": true - // }, - // ], - // }, - // "dependencyGraph": [ - // { - // "name": "plugin-a", - // "dependencies": ["plugin-b","plugin-c"] - // }, - // { - // "name": "plugin-b", - // "dependencies": ["plugin-c"] - // }, - // { - // "name": "plugin-c", - // "dependencies": [] - // } - // ] - // } - // This means, `plugin-a` depends on `plugin-b` and `plugin-c`. - // `plugin-b` depends on `plugin-c`. - // `plugin-c` doesn't depend on anything. - if (parsedFlutterPluginsDependencies) { - return parsedFlutterPluginsDependencies - } - File pluginsDependencyFile = new File(flutterSourceDirectory, flutterPluginsDependenciesFile) - if (pluginsDependencyFile.exists()) { - def object = new JsonSlurper().parseText(pluginsDependencyFile.text) - assert(object instanceof Map) - parsedFlutterPluginsDependencies = object - return object - } - return null - } -} - -// TODO(135392): Remove and use declarative form when migrated -ext { - nativePluginLoader = NativePluginLoader.instance -} diff --git a/packages/flutter_tools/test/integration.shard/android_plugin_skip_unsupported_test.dart b/packages/flutter_tools/test/integration.shard/android_plugin_skip_unsupported_test.dart deleted file mode 100644 index 58e6413bd7f0..000000000000 --- a/packages/flutter_tools/test/integration.shard/android_plugin_skip_unsupported_test.dart +++ /dev/null @@ -1,208 +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:file_testing/file_testing.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 '../src/common.dart'; -import 'test_data/plugin_each_settings_gradle_project.dart'; -import 'test_data/plugin_project.dart'; -import 'test_data/project.dart'; -import 'test_utils.dart'; - -void main() { - late Directory tempDir; - - setUp(() { - Cache.flutterRoot = getFlutterRoot(); - tempDir = createResolvedTempDirectorySync('flutter_plugin_test.'); - }); - - tearDown(() async { - tryToDelete(tempDir); - }); - - // Regression test for https://github.com/flutter/flutter/issues/97729 (#137115). - /// Creates a project which uses a plugin, which is not supported on Android. - /// This means it has no entry in pubspec.yaml for: - /// flutter -> plugin -> platforms -> android - /// - /// [createAndroidPluginFolder] indicates that the plugin can additionally - /// have a functioning `android` folder. - Future testUnsupportedPlugin({ - required Project project, - required bool createAndroidPluginFolder, - }) async { - final String flutterBin = fileSystem.path.join( - getFlutterRoot(), - 'bin', - 'flutter', - ); - - // Create dummy plugin that supports iOS and optionally Android. - processManager.runSync([ - flutterBin, - ...getLocalEngineArguments(), - 'create', - '--template=plugin', - '--platforms=ios${createAndroidPluginFolder ? ',android' : ''}', - 'test_plugin', - ], workingDirectory: tempDir.path); - - final Directory pluginAppDir = tempDir.childDirectory('test_plugin'); - - final File pubspecFile = pluginAppDir.childFile('pubspec.yaml'); - String pubspecYamlSrc = - pubspecFile.readAsStringSync().replaceAll('\r\n', '\n'); - if (createAndroidPluginFolder) { - // Override pubspec to drop support for the Android implementation. - pubspecYamlSrc = pubspecYamlSrc - .replaceFirst( - RegExp(r'name:.*\n'), - 'name: test_plugin\n', - ) - .replaceFirst(''' - android: - package: com.example.test_plugin - pluginClass: TestPlugin -''', ''' -# android: -# package: com.example.test_plugin -# pluginClass: TestPlugin -'''); - - pubspecFile.writeAsStringSync(pubspecYamlSrc); - - // Check the android directory and the build.gradle file within. - final File pluginGradleFile = - pluginAppDir.childDirectory('android').childFile('build.gradle'); - expect(pluginGradleFile, exists); - } else { - expect(pubspecYamlSrc, isNot(contains('android:'))); - } - - // Create a project which includes the plugin to test against - final Directory pluginExampleAppDir = - pluginAppDir.childDirectory('example'); - - await project.setUpIn(pluginExampleAppDir); - - // Run flutter build apk to build plugin example project. - return processManager.runSync([ - flutterBin, - ...getLocalEngineArguments(), - 'build', - 'apk', - '--debug', - ], workingDirectory: pluginExampleAppDir.path); - } - - test('skip plugin if it does not support the Android platform', () async { - final Project project = PluginWithPathAndroidProject(); - final ProcessResult buildApkResult = await testUnsupportedPlugin( - project: project, createAndroidPluginFolder: false); - expect(buildApkResult.stderr.toString(), - isNot(contains('Please fix your settings.gradle.'))); - expect(buildApkResult, const ProcessResultMatcher()); - }); - - test( - 'skip plugin with android folder if it does not support the Android platform', - () async { - final Project project = PluginWithPathAndroidProject(); - final ProcessResult buildApkResult = await testUnsupportedPlugin( - project: project, createAndroidPluginFolder: true); - expect(buildApkResult.stderr.toString(), - isNot(contains('Please fix your settings.gradle.'))); - expect(buildApkResult, const ProcessResultMatcher()); - }); - - // TODO(54566): Remove test when issue is resolved. - /// Test project with a `settings.gradle` (PluginEach) that apps were created - /// with until Flutter v1.22.0. - /// It uses the `.flutter-plugins` file to load EACH plugin. - test( - 'skip plugin if it does not support the Android platform with a _plugin.each_ settings.gradle', - () async { - final Project project = PluginEachWithPathAndroidProject(); - final ProcessResult buildApkResult = await testUnsupportedPlugin( - project: project, createAndroidPluginFolder: false); - expect(buildApkResult.stderr.toString(), - isNot(contains('Please fix your settings.gradle.'))); - expect(buildApkResult, const ProcessResultMatcher()); - }); - - // TODO(54566): Remove test when issue is resolved. - /// Test project with a `settings.gradle` (PluginEach) that apps were created - /// with until Flutter v1.22.0. - /// It uses the `.flutter-plugins` file to load EACH plugin. - /// The plugin includes a functional 'android' folder. - test( - 'skip plugin with android folder if it does not support the Android platform with a _plugin.each_ settings.gradle', - () async { - final Project project = PluginEachWithPathAndroidProject(); - final ProcessResult buildApkResult = await testUnsupportedPlugin( - project: project, createAndroidPluginFolder: true); - expect(buildApkResult.stderr.toString(), - isNot(contains('Please fix your settings.gradle'))); - expect(buildApkResult, const ProcessResultMatcher()); - }); - - // TODO(54566): Remove test when issue is resolved. - /// Test project with a `settings.gradle` (PluginEach) that apps were created - /// with until Flutter v1.22.0. - /// It is compromised by removing the 'include' statement of the plugins. - /// As the "'.flutter-plugins'" keyword is still present, the framework - /// assumes that all plugins are included, which is not the case. - /// Therefore it should throw an error. - test( - 'skip plugin if it does not support the Android platform with a compromised _plugin.each_ settings.gradle', - () async { - final Project project = PluginCompromisedEachWithPathAndroidProject(); - final ProcessResult buildApkResult = await testUnsupportedPlugin( - project: project, createAndroidPluginFolder: true); - expect( - buildApkResult, - const ProcessResultMatcher( - stderrPattern: 'Please fix your settings.gradle/settings.gradle.kts'), - ); - }); -} - -const String pubspecWithPluginPath = r''' -name: test -environment: - sdk: '>=3.2.0-0 <4.0.0' -dependencies: - flutter: - sdk: flutter - - test_plugin: - path: ../ -'''; - -/// Project that load's a plugin from the specified path. -class PluginWithPathAndroidProject extends PluginProject { - @override - String get pubspec => pubspecWithPluginPath; -} - -// TODO(54566): Remove class when issue is resolved. -/// [PluginEachSettingsGradleProject] that load's a plugin from the specified -/// path. -class PluginEachWithPathAndroidProject extends PluginEachSettingsGradleProject { - @override - String get pubspec => pubspecWithPluginPath; -} - -// TODO(54566): Remove class when issue is resolved. -/// [PluginCompromisedEachSettingsGradleProject] that load's a plugin from the -/// specified path. -class PluginCompromisedEachWithPathAndroidProject - extends PluginCompromisedEachSettingsGradleProject { - @override - String get pubspec => pubspecWithPluginPath; -} diff --git a/packages/flutter_tools/test/integration.shard/test_data/plugin_each_settings_gradle_project.dart b/packages/flutter_tools/test/integration.shard/test_data/plugin_each_settings_gradle_project.dart deleted file mode 100644 index 7747bed53d54..000000000000 --- a/packages/flutter_tools/test/integration.shard/test_data/plugin_each_settings_gradle_project.dart +++ /dev/null @@ -1,60 +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. - -// TODO(54566): Remove this file when issue is resolved. - -import 'deferred_components_config.dart'; -import 'plugin_project.dart'; - -/// Project to test the deprecated `settings.gradle` (PluginEach) that apps were -/// created with until Flutter v1.22.0. -/// It uses the `.flutter-plugins` file to load EACH plugin. -class PluginEachSettingsGradleProject extends PluginProject { - @override - DeferredComponentsConfig get deferredComponents => - PluginEachSettingsGradleDeferredComponentsConfig(); -} - -class PluginEachSettingsGradleDeferredComponentsConfig - extends PluginDeferredComponentsConfig { - @override - String get androidSettings => r''' -include ':app' -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} - '''; -} - -/// Project to test the deprecated `settings.gradle` (PluginEach) that apps were -/// created with until Flutter v1.22.0. -/// It uses the `.flutter-plugins` file to get EACH plugin. -/// It is compromised by removing the 'include' statement of the plugins. -class PluginCompromisedEachSettingsGradleProject extends PluginProject { - @override - DeferredComponentsConfig get deferredComponents => - PluginCompromisedEachSettingsGradleDeferredComponentsConfig(); -} - -class PluginCompromisedEachSettingsGradleDeferredComponentsConfig - extends PluginDeferredComponentsConfig { - @override - String get androidSettings => r''' -include ':app' -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - '''; -} diff --git a/packages/flutter_tools/test/integration.shard/test_data/plugin_project.dart b/packages/flutter_tools/test/integration.shard/test_data/plugin_project.dart deleted file mode 100644 index 2714ca627e23..000000000000 --- a/packages/flutter_tools/test/integration.shard/test_data/plugin_project.dart +++ /dev/null @@ -1,99 +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 'basic_project.dart'; -import 'deferred_components_config.dart'; -import 'deferred_components_project.dart'; - -/// Project which can load native plugins -class PluginProject extends BasicProject { - @override - final DeferredComponentsConfig? deferredComponents = - PluginDeferredComponentsConfig(); -} - -class PluginDeferredComponentsConfig extends BasicDeferredComponentsConfig { - @override - String get androidBuild => r''' -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } - configurations.classpath { - resolutionStrategy.activateDependencyLocking() - } -} -allprojects { - repositories { - google() - mavenCentral() - } -} -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') - dependencyLocking { - ignoredDependencies.add('io.flutter:*') - lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile") - if (!project.hasProperty('local-engine-repo')) { - lockAllConfigurations() - } - } -} -tasks.register("clean", Delete) { - delete rootProject.buildDir -} -'''; - - @override - String get androidSettings => r''' -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" -'''; - - @override - String get appManifest => r''' - - - - - - - - - - - - -'''; -} From 8d14d319285eead6c754cba706fbae72d3f81ac0 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 18:31:14 -0500 Subject: [PATCH 03/16] Roll Flutter Engine from bedafa8794b6 to e21208583956 (1 revision) (#142483) https://github.com/flutter/engine/compare/bedafa8794b6...e21208583956 2024-01-29 skia-flutter-autoroll@skia.org Roll Skia from 3680286e6bf4 to 0327d5b319fc (1 revision) (flutter/engine#50150) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 5ab099f38e31..6dfaac1b8cbe 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -bedafa8794b6571762978e08ee18f1c8d4c6a93b +e212085839568c171ee706a822048e1df3e7637b From 9c1665355d9b0deeec1be60b9e9137037defa877 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 19:06:26 -0500 Subject: [PATCH 04/16] Roll Flutter Engine from e21208583956 to c9268c7db03c (1 revision) (#142492) https://github.com/flutter/engine/compare/e21208583956...c9268c7db03c 2024-01-29 skia-flutter-autoroll@skia.org Roll Skia from 0327d5b319fc to c1899b2586da (3 revisions) (flutter/engine#50152) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 6dfaac1b8cbe..24ace487ded1 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -e212085839568c171ee706a822048e1df3e7637b +c9268c7db03c1d45431ee34e9e671cf98871037e From d5b189c3719a5e175e4ca707e76533be1e27245e Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 19:53:11 -0500 Subject: [PATCH 05/16] Roll Flutter Engine from c9268c7db03c to 65bf8b1db4d1 (1 revision) (#142496) https://github.com/flutter/engine/compare/c9268c7db03c...65bf8b1db4d1 2024-01-29 skia-flutter-autoroll@skia.org Roll Skia from c1899b2586da to 09379d00b455 (3 revisions) (flutter/engine#50156) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 24ace487ded1..1a849c2b44c8 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -c9268c7db03c1d45431ee34e9e671cf98871037e +65bf8b1db4d12b4c6f1c55d1b930ba69e122d1e7 From 4c62abd691e176a39f20abd9d0568be11fd32470 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 20:38:07 -0500 Subject: [PATCH 06/16] Roll Flutter Engine from 65bf8b1db4d1 to df5f1afd4991 (1 revision) (#142501) https://github.com/flutter/engine/compare/65bf8b1db4d1...df5f1afd4991 2024-01-29 johnoneil@users.noreply.github.com Enable `_Float16` "half-float" Functionality Only When Available. (flutter/engine#49851) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 1a849c2b44c8..18dd3b0a9485 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -65bf8b1db4d12b4c6f1c55d1b930ba69e122d1e7 +df5f1afd499189a0a26f99465fc462d01b851e2e From bce0a84bffa7e8295c7bedbbdac5c28a5c1162b1 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 21:17:36 -0500 Subject: [PATCH 07/16] Roll Flutter Engine from df5f1afd4991 to 5584a78a439b (2 revisions) (#142503) https://github.com/flutter/engine/compare/df5f1afd4991...5584a78a439b 2024-01-30 matanlurey@users.noreply.github.com Revert: "Change how OpenGL textures are flipped in the Android embedder" (flutter/engine#50158) 2024-01-30 john@johnmccutchan.com Re-Re-land Manually revert TLHC optimizations (flutter/engine#50155) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 18dd3b0a9485..f3f5a0a1ed43 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -df5f1afd499189a0a26f99465fc462d01b851e2e +5584a78a439b49630f0cf01e7a72399292f838c3 From 5c64d0370b0d9e4d5c9f808ec8247ed0ab65c80a Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Mon, 29 Jan 2024 22:21:25 -0500 Subject: [PATCH 08/16] Roll Flutter Engine from 5584a78a439b to ed73d40a8c93 (1 revision) (#142504) https://github.com/flutter/engine/compare/5584a78a439b...ed73d40a8c93 2024-01-30 skia-flutter-autoroll@skia.org Roll Skia from 09379d00b455 to 083c1a4d9767 (1 revision) (flutter/engine#50162) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index f3f5a0a1ed43..5470911c8101 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -5584a78a439b49630f0cf01e7a72399292f838c3 +ed73d40a8c9340dc0d9c2e2a859d02b876dc9858 From 6dff3da31cd08233d2d8fbf13ed4ddf6a79004d9 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Mon, 29 Jan 2024 21:21:34 -0800 Subject: [PATCH 09/16] Organize leak tracking TODOs. (#142460) --- .../test/animation/live_binding_test.dart | 2 +- .../flutter/test/cupertino/refresh_test.dart | 2 +- .../test/material/circle_avatar_test.dart | 2 +- .../test/material/input_decorator_test.dart | 2 +- .../flutter/test/material/scaffold_test.dart | 2 +- .../painting/decoration_image_lerp_test.dart | 6 ++-- .../test/painting/image_stream_test.dart | 2 +- .../test/painting/system_fonts_test.dart | 2 +- .../semantics/semantics_elevation_test.dart | 2 +- packages/flutter/test/widgets/basic_test.dart | 2 +- .../widgets/context_menu_controller_test.dart | 4 +-- .../flutter/test/widgets/draggable_test.dart | 2 +- packages/flutter/test/widgets/image_test.dart | 24 +++++++-------- .../test/widgets/nested_scroll_view_test.dart | 5 +--- .../widgets/overscroll_indicator_test.dart | 2 +- .../flutter/test/widgets/page_view_test.dart | 29 +++++-------------- .../test/widgets/pageable_list_test.dart | 6 +--- .../scroll_aware_image_provider_test.dart | 15 ++++++---- .../widgets/scrollable_restoration_test.dart | 12 ++------ ...ssion_for_current_semantics_tree_test.dart | 2 +- .../test/widgets/shape_decoration_test.dart | 2 +- .../tracking_scroll_controller_test.dart | 11 ++----- 22 files changed, 54 insertions(+), 84 deletions(-) diff --git a/packages/flutter/test/animation/live_binding_test.dart b/packages/flutter/test/animation/live_binding_test.dart index 60f8401a194f..33692e66eed8 100644 --- a/packages/flutter/test/animation/live_binding_test.dart +++ b/packages/flutter/test/animation/live_binding_test.dart @@ -79,7 +79,7 @@ void main() { }, skip: true); // Typically skip: isBrowser https://github.com/flutter/flutter/issues/42767 testWidgets('Should show event indicator for pointer events with setSurfaceSize', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(200, 200), allLayers: true); diff --git a/packages/flutter/test/cupertino/refresh_test.dart b/packages/flutter/test/cupertino/refresh_test.dart index 7a4b37ae73af..fb66030fe7db 100644 --- a/packages/flutter/test/cupertino/refresh_test.dart +++ b/packages/flutter/test/cupertino/refresh_test.dart @@ -36,7 +36,7 @@ void main() { void uiTestGroup() { testWidgets("doesn't invoke anything without user interaction", - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget( diff --git a/packages/flutter/test/material/circle_avatar_test.dart b/packages/flutter/test/material/circle_avatar_test.dart index 72b297516c0f..6fafdfb88868 100644 --- a/packages/flutter/test/material/circle_avatar_test.dart +++ b/packages/flutter/test/material/circle_avatar_test.dart @@ -96,7 +96,7 @@ void main() { }); testWidgets('CircleAvatar backgroundImage is used as a fallback for foregroundImage', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final ErrorImageProvider errorImage = ErrorImageProvider(); diff --git a/packages/flutter/test/material/input_decorator_test.dart b/packages/flutter/test/material/input_decorator_test.dart index 986d867bbcec..26922efed168 100644 --- a/packages/flutter/test/material/input_decorator_test.dart +++ b/packages/flutter/test/material/input_decorator_test.dart @@ -170,7 +170,7 @@ void main() { void runAllTests({ required bool useMaterial3 }) { testWidgets('InputDecorator input/label text layout', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { // The label appears above the input text diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index d1aab5b5087a..7fc2ff30146f 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -2207,7 +2207,7 @@ void main() { testWidgets( 'didUpdate bottomSheet while a previous bottom sheet is still displayed', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final GlobalKey key = GlobalKey(); diff --git a/packages/flutter/test/painting/decoration_image_lerp_test.dart b/packages/flutter/test/painting/decoration_image_lerp_test.dart index 7b9ec33d47b3..fbdc03918f5c 100644 --- a/packages/flutter/test/painting/decoration_image_lerp_test.dart +++ b/packages/flutter/test/painting/decoration_image_lerp_test.dart @@ -18,7 +18,7 @@ import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { testWidgets('ImageDecoration.lerp', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage green = MemoryImage(Uint8List.fromList([ @@ -195,7 +195,7 @@ void main() { }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609 testWidgets('ImageDecoration.lerp', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage cmyk = MemoryImage(Uint8List.fromList([ @@ -416,7 +416,7 @@ void main() { }, skip: kIsWeb); // TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609 testWidgets('ImageDecoration.lerp with colored background', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final MemoryImage cmyk = MemoryImage(Uint8List.fromList([ diff --git a/packages/flutter/test/painting/image_stream_test.dart b/packages/flutter/test/painting/image_stream_test.dart index 615596e4b817..e29cd450527f 100644 --- a/packages/flutter/test/painting/image_stream_test.dart +++ b/packages/flutter/test/painting/image_stream_test.dart @@ -78,7 +78,7 @@ class FakeEventReportingImageStreamCompleter extends ImageStreamCompleter { } void main() { - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] LeakTesting.settings = LeakTesting.settings.withIgnoredAll(); late Image image20x10; diff --git a/packages/flutter/test/painting/system_fonts_test.dart b/packages/flutter/test/painting/system_fonts_test.dart index c4a43b875ccc..3aa495a86fd3 100644 --- a/packages/flutter/test/painting/system_fonts_test.dart +++ b/packages/flutter/test/painting/system_fonts_test.dart @@ -38,7 +38,7 @@ Future verifyMarkedNeedsLayoutDuringTransientCallbacksPhase(WidgetTester t void main() { testWidgets('RenderParagraph relayout upon system fonts changes', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget( diff --git a/packages/flutter/test/semantics/semantics_elevation_test.dart b/packages/flutter/test/semantics/semantics_elevation_test.dart index 34eea21fa95a..b9d37d0bc60c 100644 --- a/packages/flutter/test/semantics/semantics_elevation_test.dart +++ b/packages/flutter/test/semantics/semantics_elevation_test.dart @@ -11,7 +11,7 @@ import '../widgets/semantics_tester.dart'; void main() { testWidgets('SemanticsNodes overlapping in z', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { // Cards are semantic boundaries that always own their own SemanticNode, diff --git a/packages/flutter/test/widgets/basic_test.dart b/packages/flutter/test/widgets/basic_test.dart index e15a01c097ca..b33885dc0931 100644 --- a/packages/flutter/test/widgets/basic_test.dart +++ b/packages/flutter/test/widgets/basic_test.dart @@ -22,7 +22,7 @@ import 'semantics_tester.dart'; void main() { group('RawImage', () { testWidgets('properties', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final ui.Image image1 = (await tester.runAsync(() => createTestImage()))!; diff --git a/packages/flutter/test/widgets/context_menu_controller_test.dart b/packages/flutter/test/widgets/context_menu_controller_test.dart index 71ddff699474..a161f4394587 100644 --- a/packages/flutter/test/widgets/context_menu_controller_test.dart +++ b/packages/flutter/test/widgets/context_menu_controller_test.dart @@ -92,7 +92,7 @@ void main() { }); testWidgets('A menu can be hidden and then reshown', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final GlobalKey key1 = GlobalKey(); @@ -183,7 +183,7 @@ void main() { }); testWidgets('Calling show when a built-in widget is already showing its context menu hides the built-in menu', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final GlobalKey builtInKey = GlobalKey(); diff --git a/packages/flutter/test/widgets/draggable_test.dart b/packages/flutter/test/widgets/draggable_test.dart index 5af50d9af422..04d30b64b728 100644 --- a/packages/flutter/test/widgets/draggable_test.dart +++ b/packages/flutter/test/widgets/draggable_test.dart @@ -3432,7 +3432,7 @@ void main() { // Regression test for https://github.com/flutter/flutter/issues/92083 testWidgets('feedback respect the MouseRegion cursor configure', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/image_test.dart b/packages/flutter/test/widgets/image_test.dart index ec281efca509..34b6e024fda9 100644 --- a/packages/flutter/test/widgets/image_test.dart +++ b/packages/flutter/test/widgets/image_test.dart @@ -798,7 +798,7 @@ void main() { }); testWidgets('Precache', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final _TestImageProvider provider = _TestImageProvider(); @@ -823,7 +823,7 @@ void main() { }); testWidgets('Precache removes original listener immediately after future completes, does not crash on successive calls #25143', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final _TestImageStreamCompleter imageStreamCompleter = _TestImageStreamCompleter(); @@ -1021,7 +1021,7 @@ void main() { }); testWidgets('Image invokes frameBuilder with correct frameNumber argument', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final ui.Codec codec = (await tester.runAsync(() { @@ -1093,7 +1093,7 @@ void main() { }); testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=true', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final _TestImageStreamCompleter streamCompleter = _TestImageStreamCompleter(ImageInfo(image: image10x10.clone())); @@ -1154,7 +1154,7 @@ void main() { }); testWidgets('Image state handles enabling and disabling of tickers', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final ui.Codec codec = (await tester.runAsync(() { @@ -1565,7 +1565,7 @@ void main() { }); testWidgets('precacheImage does not hold weak ref for more than a frame', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { imageCache.maximumSize = 0; @@ -1619,7 +1619,7 @@ void main() { }); testWidgets('precacheImage allows time to take over weak reference', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final _TestImageProvider provider = _TestImageProvider(); @@ -1673,7 +1673,7 @@ void main() { }); testWidgets('evict an image during precache', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { // This test checks that the live image tracking does not hold on to a @@ -1790,7 +1790,7 @@ void main() { testWidgets( 'Rotated images', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await testRotatedImage(tester, true); @@ -1801,7 +1801,7 @@ void main() { testWidgets( 'Image opacity', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final Key key = UniqueKey(); @@ -1852,7 +1852,7 @@ void main() { ); testWidgets('Reports image size when painted', - // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { late ImageSizeInfo imageSizeInfo; @@ -1964,7 +1964,7 @@ void main() { }); testWidgets('Load a good image after a bad image was loaded should not call errorBuilder', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final UniqueKey errorKey = UniqueKey(); diff --git a/packages/flutter/test/widgets/nested_scroll_view_test.dart b/packages/flutter/test/widgets/nested_scroll_view_test.dart index fbf84f5188f7..94a4d16137a8 100644 --- a/packages/flutter/test/widgets/nested_scroll_view_test.dart +++ b/packages/flutter/test/widgets/nested_scroll_view_test.dart @@ -534,10 +534,7 @@ void main() { expect(find.text('ddd1'), findsOneWidget); }); - testWidgets('Three NestedScrollViews with one ScrollController', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('Three NestedScrollViews with one ScrollController', (WidgetTester tester) async { final TrackingScrollController controller = TrackingScrollController(); addTearDown(controller.dispose); expect(controller.mostRecentlyUpdatedPosition, isNull); diff --git a/packages/flutter/test/widgets/overscroll_indicator_test.dart b/packages/flutter/test/widgets/overscroll_indicator_test.dart index 659c4bc4c4db..b647416216e5 100644 --- a/packages/flutter/test/widgets/overscroll_indicator_test.dart +++ b/packages/flutter/test/widgets/overscroll_indicator_test.dart @@ -293,7 +293,7 @@ void main() { }); testWidgets('Nested overscrolls do not throw exceptions', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget(Directionality( diff --git a/packages/flutter/test/widgets/page_view_test.dart b/packages/flutter/test/widgets/page_view_test.dart index 3dd159355ee5..aa6d305a3072 100644 --- a/packages/flutter/test/widgets/page_view_test.dart +++ b/packages/flutter/test/widgets/page_view_test.dart @@ -7,7 +7,6 @@ import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../rendering/rendering_tester.dart' show TestClipPaintingContext; import 'semantics_tester.dart'; @@ -15,10 +14,7 @@ import 'states.dart'; void main() { // Regression test for https://github.com/flutter/flutter/issues/100451 - testWidgets('PageView.builder respects findChildIndexCallback', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageView.builder respects findChildIndexCallback', (WidgetTester tester) async { bool finderCalled = false; int itemCount = 7; late StateSetter stateSetter; @@ -333,10 +329,7 @@ void main() { expect(find.text('California'), findsOneWidget); }); - testWidgets('PageController page stability', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageController page stability', (WidgetTester tester) async { await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, child: Center( @@ -422,10 +415,7 @@ void main() { expect(previousPageCompleted, true); }); - testWidgets('PageView in zero-size container', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageView in zero-size container', (WidgetTester tester) async { await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, child: Center( @@ -605,10 +595,7 @@ void main() { expect(tester.getTopLeft(find.text('Idaho')), const Offset(790.0, 0.0)); }); - testWidgets('Page snapping disable and reenable', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('Page snapping disable and reenable', (WidgetTester tester) async { final List log = []; Widget build({ required bool pageSnapping }) { @@ -1333,20 +1320,20 @@ void main() { } Future testPageViewWithController(PageController controller, WidgetTester tester, bool controls) async { - int curentVisiblePage() { + int currentVisiblePage() { return int.parse(tester.widgetList(find.byType(Text)).whereType().first.data!); } - final int initialPageInView = curentVisiblePage(); + final int initialPageInView = currentVisiblePage(); for (int i = 0; i < 3; i++) { if (controls) { controller.jumpToPage(i); await tester.pumpAndSettle(); - expect(curentVisiblePage(), i); + expect(currentVisiblePage(), i); } else { expect(()=> controller.jumpToPage(i), throwsAssertionError); - expect(curentVisiblePage(), initialPageInView); + expect(currentVisiblePage(), initialPageInView); } } } diff --git a/packages/flutter/test/widgets/pageable_list_test.dart b/packages/flutter/test/widgets/pageable_list_test.dart index 135fe7e5c4e8..3cab09a14c5f 100644 --- a/packages/flutter/test/widgets/pageable_list_test.dart +++ b/packages/flutter/test/widgets/pageable_list_test.dart @@ -4,7 +4,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; Size pageSize = const Size(600.0, 300.0); const List defaultPages = [0, 1, 2, 3, 4, 5]; @@ -60,10 +59,7 @@ Future pageRight(WidgetTester tester) { } void main() { - testWidgets('PageView default control', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageView default control', (WidgetTester tester) async { await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, diff --git a/packages/flutter/test/widgets/scroll_aware_image_provider_test.dart b/packages/flutter/test/widgets/scroll_aware_image_provider_test.dart index e5f1e8b6b844..d0968ec32b81 100644 --- a/packages/flutter/test/widgets/scroll_aware_image_provider_test.dart +++ b/packages/flutter/test/widgets/scroll_aware_image_provider_test.dart @@ -35,7 +35,7 @@ void main() { } testWidgets('ScrollAwareImageProvider does not delay if widget is not in scrollable', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final GlobalKey key = GlobalKey(); @@ -65,7 +65,10 @@ void main() { expect(imageCache.currentSize, 1); }); - testWidgets('ScrollAwareImageProvider does not delay if in scrollable that is not scrolling', (WidgetTester tester) async { + testWidgets('ScrollAwareImageProvider does not delay if in scrollable that is not scrolling', + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] + experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), + (WidgetTester tester) async { final GlobalKey key = GlobalKey(); await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -103,7 +106,7 @@ void main() { }); testWidgets('ScrollAwareImageProvider does not delay if in scrollable that is scrolling slowly', - // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 + // TODO(polina-c): make sure images are disposed, https://github.com/flutter/flutter/issues/141388 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final List> keys = >[]; @@ -234,7 +237,7 @@ void main() { }); testWidgets('ScrollAwareImageProvider delays if in scrollable that is scrolling fast and fizzles if disposed', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final List> keys = >[]; @@ -308,7 +311,7 @@ void main() { }); testWidgets('ScrollAwareImageProvider resolves from ImageCache and does not set completer twice', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final GlobalKey key = GlobalKey(); @@ -361,7 +364,7 @@ void main() { }); testWidgets('ScrollAwareImageProvider does not block LRU updates to image cache', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final int oldSize = imageCache.maximumSize; diff --git a/packages/flutter/test/widgets/scrollable_restoration_test.dart b/packages/flutter/test/widgets/scrollable_restoration_test.dart index 7fc947807768..d0b72937c499 100644 --- a/packages/flutter/test/widgets/scrollable_restoration_test.dart +++ b/packages/flutter/test/widgets/scrollable_restoration_test.dart @@ -264,7 +264,7 @@ void main() { }); testWidgets('PageView restoration', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget( @@ -282,10 +282,7 @@ void main() { await pageViewScrollAndRestore(tester); }); - testWidgets('PageView.builder restoration', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageView.builder restoration', (WidgetTester tester) async { await tester.pumpWidget( TestHarness( child: PageView.builder( @@ -301,10 +298,7 @@ void main() { await pageViewScrollAndRestore(tester); }); - testWidgets('PageView.custom restoration', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('PageView.custom restoration', (WidgetTester tester) async { await tester.pumpWidget( TestHarness( child: PageView.custom( diff --git a/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart b/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart index 57f2c5740c02..1f3267983bff 100644 --- a/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart +++ b/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart @@ -54,7 +54,7 @@ void _tests() { // // This test is flexible w.r.t. leading and trailing whitespace. testWidgets('generates code', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); diff --git a/packages/flutter/test/widgets/shape_decoration_test.dart b/packages/flutter/test/widgets/shape_decoration_test.dart index 83def39cb274..1ef7cad4f266 100644 --- a/packages/flutter/test/widgets/shape_decoration_test.dart +++ b/packages/flutter/test/widgets/shape_decoration_test.dart @@ -19,7 +19,7 @@ Future main() async { final ImageProvider image = TestImageProvider(0, 0, image: rawImage); testWidgets('ShapeDecoration.image', - // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 + // TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean] experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), (WidgetTester tester) async { await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/tracking_scroll_controller_test.dart b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart index d9d8cb1a7d2b..884583e1139f 100644 --- a/packages/flutter/test/widgets/tracking_scroll_controller_test.dart +++ b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart @@ -4,13 +4,9 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_testing/leak_tracker_testing.dart'; void main() { - testWidgets('TrackingScrollController saves offset', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('TrackingScrollController saves offset', (WidgetTester tester) async { final TrackingScrollController controller = TrackingScrollController(); addTearDown(controller.dispose); const double listItemHeight = 100.0; @@ -64,10 +60,7 @@ void main() { expect(controller.initialScrollOffset, 0.0); }); - testWidgets('TrackingScrollController saves offset', - // TODO(polina-c): Remove when PageView is fixed, https://github.com/flutter/flutter/issues/141119 - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('TrackingScrollController saves offset', (WidgetTester tester) async { int attach = 0; int detach = 0; final TrackingScrollController controller = TrackingScrollController( From 40ecbc81b9cb18f7fd558e9e1a8b154fe82a8dfe Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 30 Jan 2024 00:33:32 -0500 Subject: [PATCH 10/16] Roll Flutter Engine from ed73d40a8c93 to 438e9b4d7d4e (1 revision) (#142508) https://github.com/flutter/engine/compare/ed73d40a8c93...438e9b4d7d4e 2024-01-30 mbrase@google.com Fix incorrect FML_VLOG() severity usage (flutter/engine#50118) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jacksongardner@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 5470911c8101..67d47307c9e7 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -ed73d40a8c9340dc0d9c2e2a859d02b876dc9858 +438e9b4d7d4e4031379a930294b6b2c6fbb8079c From ccb2b4439a430d4a736bcb294ba8f00be79fc66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rulong=20Chen=EF=BC=88=E9=99=88=E6=B1=9D=E9=BE=99=EF=BC=89?= <26625149+0xZOne@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:59:24 +0800 Subject: [PATCH 11/16] Using `initExpensiveAndroidView` for Android Hybrid Composition Mode (#142399) After https://github.com/flutter/flutter/pull/100990, we should use `initExpensiveAndroidView` for Android Hybrid Composition mode instead of `initSurfaceAndroidView`. `initSurfaceAndroidView` attempts to use `TLHC` when possible. In cases where that is not supported, it falls back to using Hybrid Composition. https://github.com/flutter/engine/pull/49414 --- .../lib/android_platform_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/benchmarks/platform_views_layout_hybrid_composition/lib/android_platform_view.dart b/dev/benchmarks/platform_views_layout_hybrid_composition/lib/android_platform_view.dart index 1153fdf89526..def05d9a3999 100644 --- a/dev/benchmarks/platform_views_layout_hybrid_composition/lib/android_platform_view.dart +++ b/dev/benchmarks/platform_views_layout_hybrid_composition/lib/android_platform_view.dart @@ -34,7 +34,7 @@ class AndroidPlatformView extends StatelessWidget { ); }, onCreatePlatformView: (PlatformViewCreationParams params) { - return PlatformViewsService.initSurfaceAndroidView( + return PlatformViewsService.initExpensiveAndroidView( id: params.id, viewType: viewType, layoutDirection: TextDirection.ltr, From 72dc162ff052ef414304ff724785bb29b915c8c5 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 30 Jan 2024 10:13:06 -0500 Subject: [PATCH 12/16] Roll Flutter Engine from 438e9b4d7d4e to 0e586d1c28c8 (4 revisions) (#142515) https://github.com/flutter/engine/compare/438e9b4d7d4e...0e586d1c28c8 2024-01-30 jonahwilliams@google.com [Impeller] Add interface for submitting multiple command buffers at once. (flutter/engine#50139) 2024-01-30 49699333+dependabot[bot]@users.noreply.github.com Bump actions/upload-artifact from 4.1.0 to 4.3.0 (flutter/engine#50165) 2024-01-30 skia-flutter-autoroll@skia.org Roll Skia from 083c1a4d9767 to 4e992fb3a9db (1 revision) (flutter/engine#50164) 2024-01-30 mbrase@google.com Use structured logging on Fuchsia (flutter/engine#49918) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC matanl@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 67d47307c9e7..86ba508d08aa 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -438e9b4d7d4e4031379a930294b6b2c6fbb8079c +0e586d1c28c868d59f7fbe9402938fc5dc448b85 From 461f0bfb4b84efde9f5d360193ba14f55abcfce0 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 30 Jan 2024 10:38:31 -0500 Subject: [PATCH 13/16] Roll Packages from 516648afb6be to 25abb5d1e0de (6 revisions) (#142527) https://github.com/flutter/packages/compare/516648afb6be...25abb5d1e0de 2024-01-30 tessertaha@gmail.com [rfw] Add `OverflowBar` widget and Update `ButtonBar` widget implementation (flutter/packages#5807) 2024-01-30 stuartmorgan@google.com [ci] Reduce tasks slightly (flutter/packages#6011) 2024-01-29 stuartmorgan@google.com Clarify issue requirement (flutter/packages#6010) 2024-01-29 stuartmorgan@google.com [various] Disambiguate TestDefaultBinaryMessengerBinding (flutter/packages#6009) 2024-01-29 engine-flutter-autoroll@skia.org Manual roll Flutter from a8efa771d6a3 to 2f6fdf2650d4 (23 revisions) (flutter/packages#6008) 2024-01-29 49699333+dependabot[bot]@users.noreply.github.com Bump github/codeql-action from 3.23.1 to 3.23.2 (flutter/packages#5987) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/flutter_packages.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/internal/flutter_packages.version b/bin/internal/flutter_packages.version index d1222ef42aaf..b5cc994c215b 100644 --- a/bin/internal/flutter_packages.version +++ b/bin/internal/flutter_packages.version @@ -1 +1 @@ -516648afb6be32b2d43215d8439ab2956d302577 +25abb5d1e0de3352299a070d71ab2428fcae988a From 5bb4fa35f32959654d1757b63f93c5c040877522 Mon Sep 17 00:00:00 2001 From: engine-flutter-autoroll Date: Tue, 30 Jan 2024 10:57:08 -0500 Subject: [PATCH 14/16] Roll Flutter Engine from 0e586d1c28c8 to f02a4a80a77e (3 revisions) (#142528) https://github.com/flutter/engine/compare/0e586d1c28c8...f02a4a80a77e 2024-01-30 skia-flutter-autoroll@skia.org Roll Skia from 1c0eae94fc09 to 7dc9ba2e8c90 (1 revision) (flutter/engine#50169) 2024-01-30 skia-flutter-autoroll@skia.org Roll Skia from 4e992fb3a9db to 1c0eae94fc09 (3 revisions) (flutter/engine#50167) 2024-01-30 skia-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Hqi_x_A9lYsY58VSn... to Z-xFM2ILZJw22eU8q... (flutter/engine#50166) Also rolling transitive DEPS: fuchsia/sdk/core/linux-amd64 from Hqi_x_A9lYsY to Z-xFM2ILZJw2 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC matanl@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- bin/internal/engine.version | 2 +- bin/internal/fuchsia-linux.version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 86ba508d08aa..e32a0fa13e88 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -0e586d1c28c868d59f7fbe9402938fc5dc448b85 +f02a4a80a77e3caba02a905957c495c1716cca22 diff --git a/bin/internal/fuchsia-linux.version b/bin/internal/fuchsia-linux.version index 2d6fb0cc7bc1..5dd566f9f2a3 100644 --- a/bin/internal/fuchsia-linux.version +++ b/bin/internal/fuchsia-linux.version @@ -1 +1 @@ -Hqi_x_A9lYsY58VSnSoF0H5QBihWbm3_P_lpgLjIkrYC +Z-xFM2ILZJw22eU8qOl52sPcOgS3CQtJ1LkWDRe_dtwC From e8cb02958373e7191b030f003a65c4d9682842f2 Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Tue, 30 Jan 2024 10:04:13 -0600 Subject: [PATCH 15/16] Fix SliverMainAxisGroup geometry cacheExtent (#142482) Fixes https://github.com/flutter/flutter/issues/142183 This fixes a bug in the SliverGeometry of SliverMainAxisGroup. The cacheExtent represents how many pixels the sliver has consumed in the SliverConstraints.remainingCacheExtent. Since it was not set, slivers that came after a SliverMainAxisGroup that filled the whole screen did not properly lay out their own children, in some cases making lazy sliver more eager than they should be. --- .../lib/src/rendering/sliver_group.dart | 14 +++++++- .../widgets/sliver_main_axis_group_test.dart | 36 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/rendering/sliver_group.dart b/packages/flutter/lib/src/rendering/sliver_group.dart index 40e8ee85ec7b..e336602dfb1f 100644 --- a/packages/flutter/lib/src/rendering/sliver_group.dart +++ b/packages/flutter/lib/src/rendering/sliver_group.dart @@ -284,9 +284,21 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM offset += child.geometry!.scrollExtent; child = childAfter(child); } + + final double paintExtent = calculatePaintOffset( + constraints, + from: math.min(constraints.scrollOffset, 0), + to: totalScrollExtent, + ); + final double cacheExtent = calculateCacheOffset( + constraints, + from: math.min(constraints.scrollOffset, 0), + to: totalScrollExtent, + ); geometry = SliverGeometry( scrollExtent: totalScrollExtent, - paintExtent: calculatePaintOffset(constraints, from: 0, to: totalScrollExtent), + paintExtent: paintExtent, + cacheExtent: cacheExtent, maxPaintExtent: maxPaintExtent, hasVisualOverflow: totalScrollExtent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0, ); diff --git a/packages/flutter/test/widgets/sliver_main_axis_group_test.dart b/packages/flutter/test/widgets/sliver_main_axis_group_test.dart index b0cf025e260e..49cabeae38d7 100644 --- a/packages/flutter/test/widgets/sliver_main_axis_group_test.dart +++ b/packages/flutter/test/widgets/sliver_main_axis_group_test.dart @@ -692,6 +692,42 @@ void main() { expect(controller.offset, 1000); expect(counter, equals(2)); }); + + testWidgets('SliverMainAxisGroup does not cause extra builds for lazy sliver children', (WidgetTester tester) async { + // By setting the correct SliverGeometry in the first SliverMainAxisGroup, + // the following SliverMainAxisGroups will not perform extra work. + final Map buildsPerGroup = { + 0 : 0, + 1 : 0, + 2 : 0, + }; + await tester.pumpWidget(MaterialApp( + home: CustomScrollView( + slivers: [ + for (int groupIndex = 0; groupIndex < 3; groupIndex++) + SliverMainAxisGroup( + slivers: [ + SliverList.builder( + itemCount: 100, + itemBuilder: (BuildContext context, int index) { + buildsPerGroup[groupIndex] = buildsPerGroup[groupIndex]! + 1; + return const SizedBox.square(dimension: 50); + }, + ), + ], + ), + ] + ), + )); + await tester.pumpAndSettle(); + expect(buildsPerGroup[0], 17); // First sliver filled the screen and cache extent + expect(buildsPerGroup[1], 1); // Second only lays out one child + expect(buildsPerGroup[2], 1); // Third only lays out one child + final RenderSliverMainAxisGroup renderGroup = tester.renderObject( + find.byType(SliverMainAxisGroup).first, + ) as RenderSliverMainAxisGroup; + expect(renderGroup.geometry!.cacheExtent, 850.0); + }); } Widget _buildSliverList({ From 75a2e5b4932a27c0d69a7929786d96b202e2adc1 Mon Sep 17 00:00:00 2001 From: Aizat Azhar <39623254+aizatazhar@users.noreply.github.com> Date: Wed, 31 Jan 2024 00:04:15 +0800 Subject: [PATCH 16/16] Reset framesEnabled to default value at the end of each test (#141844) Reset `framesEnabled` to `true` at the end of each test as otherwise subsequent tests may fail when pumping a widget Fixes #141835 --- packages/flutter/lib/src/scheduler/binding.dart | 7 ++++--- .../flutter/test/services/lifecycle_test.dart | 4 ++-- .../test/widgets/app_lifecycle_listener_test.dart | 2 +- packages/flutter/test/widgets/binding_test.dart | 15 +++++++++++++++ packages/flutter_test/lib/src/binding.dart | 2 +- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index 6bad5b1c6faf..7d4af952a861 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -391,11 +391,12 @@ mixin SchedulerBinding on BindingBase { AppLifecycleState? get lifecycleState => _lifecycleState; AppLifecycleState? _lifecycleState; - /// Allows the test framework to reset the lifecycle state back to its - /// initial value. + /// Allows the test framework to reset the lifecycle state and framesEnabled + /// back to their initial values. @visibleForTesting - void resetLifecycleState() { + void resetInternalState() { _lifecycleState = null; + _framesEnabled = true; } /// Called when the application lifecycle state changes. diff --git a/packages/flutter/test/services/lifecycle_test.dart b/packages/flutter/test/services/lifecycle_test.dart index 588cfd42c1c1..af25e93e245c 100644 --- a/packages/flutter/test/services/lifecycle_test.dart +++ b/packages/flutter/test/services/lifecycle_test.dart @@ -10,7 +10,7 @@ import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('initialLifecycleState is used to init state paused', (WidgetTester tester) async { final TestWidgetsFlutterBinding binding = tester.binding; - binding.resetLifecycleState(); + binding.resetInternalState(); // Use paused as the initial state. binding.platformDispatcher.initialLifecycleStateTestValue = 'AppLifecycleState.paused'; binding.readTestInitialLifecycleStateFromNativeWindow(); // Re-attempt the initialization. @@ -22,7 +22,7 @@ void main() { testWidgets('Handles all of the allowed states of AppLifecycleState', (WidgetTester tester) async { final TestWidgetsFlutterBinding binding = tester.binding; for (final AppLifecycleState state in AppLifecycleState.values) { - binding.resetLifecycleState(); + binding.resetInternalState(); binding.platformDispatcher.initialLifecycleStateTestValue = state.toString(); binding.readTestInitialLifecycleStateFromNativeWindow(); expect(ServicesBinding.instance.lifecycleState.toString(), equals(state.toString())); diff --git a/packages/flutter/test/widgets/app_lifecycle_listener_test.dart b/packages/flutter/test/widgets/app_lifecycle_listener_test.dart index b9dfc798299c..9e0ec667952a 100644 --- a/packages/flutter/test/widgets/app_lifecycle_listener_test.dart +++ b/packages/flutter/test/widgets/app_lifecycle_listener_test.dart @@ -43,7 +43,7 @@ void main() { listener?.dispose(); listener = null; final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance; - binding.resetLifecycleState(); + binding.resetInternalState(); binding.platformDispatcher.resetInitialLifecycleState(); assert(TestAppLifecycleListener.registerCount == 0, 'There were ${TestAppLifecycleListener.registerCount} listeners that were not disposed of in tests.'); diff --git a/packages/flutter/test/widgets/binding_test.dart b/packages/flutter/test/widgets/binding_test.dart index b42df5fe0943..d7f714786110 100644 --- a/packages/flutter/test/widgets/binding_test.dart +++ b/packages/flutter/test/widgets/binding_test.dart @@ -397,6 +397,21 @@ void main() { await tester.pump(); }); + testWidgets('resetInternalState resets lifecycleState and framesEnabled to initial state', (WidgetTester tester) async { + // Initial state + expect(tester.binding.lifecycleState, isNull); + expect(tester.binding.framesEnabled, isTrue); + + tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.paused); + expect(tester.binding.lifecycleState, AppLifecycleState.paused); + expect(tester.binding.framesEnabled, isFalse); + + tester.binding.resetInternalState(); + + expect(tester.binding.lifecycleState, isNull); + expect(tester.binding.framesEnabled, isTrue); + }); + testWidgets('scheduleFrameCallback error control test', (WidgetTester tester) async { late FlutterError error; try { diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart index 9e77db40857e..87db72f48d7b 100644 --- a/packages/flutter_test/lib/src/binding.dart +++ b/packages/flutter_test/lib/src/binding.dart @@ -1177,7 +1177,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase // ignore: invalid_use_of_visible_for_testing_member RendererBinding.instance.initMouseTracker(); // ignore: invalid_use_of_visible_for_testing_member - ServicesBinding.instance.resetLifecycleState(); + ServicesBinding.instance.resetInternalState(); } }