Repository navigation
[AGP 9.1.0 Migration #8] Unify add-to-app module wiring on the variant API - #193717
reidbaker-agent wants to merge 11 commits into
Conversation
The application path of the Flutter Gradle Plugin no longer uses the deprecated BaseVariant API (applicationVariants / ApkVariantOutput): - CopyFlutterApksTask copies the variant's SingleArtifact.APK outputs, read through BuiltArtifactsLoader, into build/outputs/flutter-apk under the unchanged names app[-abi][-flavor]-<mode>.apk. assemble<Variant> depends on it. The task has no Project or variant fields and uses an injected FileSystemOperations. - A single naming function in the task produces both the declared @OutputFiles and the copied file names. Its inputs are the ABIs of the variant's outputs (what AGP builds), the flavor, and the build mode. The task fails if AGP built an APK for an ABI that was not declared. - Per-ABI versionCode for --split-per-abi is a read-then-set on VariantOutput.versionCode in onVariants. This is a documented exception to the no-configuration-time-get rule, because the lazy form is circular. The read relies on AGP's compatibility mode (android.compatibility.enableLegacyApi, on by default through 9.x). - The applicationVariants.configureEach block and its @Suppress("DEPRECATION") markers are deleted. The add-to-app module path keeps using libraryVariants until the next phase. Behavior change: Flutter's onVariants callback runs before an app's own androidComponents.onVariants block, while ApkVariantOutput's versionCodeOverride was applied after it. Apps that transform output.versionCode there transform Flutter's offset value (for example arm64-v8a, build 42, x10000: 422000 -> 20420000). The migration doc and the breaking-change page draft describe this and give a recipe that keeps the 422000-style numbers. No divergence warning is emitted, because it would fire on the onVariants pattern that AGP recommends. Part of flutter#166550.
…ures - Take the per-ABI versionCode base from a finalizeDsl snapshot of the DSL versionCodes (DslVersionCodes) instead of reading output.versionCode, which AGP rejects during configuration when android.compatibility.enableLegacyApi=false. Warn and skip when the DSL declares no versionCode. - Add a strict-mode (enableLegacyApi=false) case to flutter_build_apk_split_per_abi_test. - CopyFlutterApksTask: use Gradle's Copy/Sync caching annotation and reason; explain when the metadata can be missing and when the ABI check can fail; point both errors at the plugin that transforms SingleArtifact.APK instead of asking for a Flutter issue. - Document what an APK transform must keep in website-page-draft.md. - Link the website-page-draft.md references to tracking issue flutter#193713. - Remove temporal wording from KDoc and docs.
Add-to-app module (library) variants use the same androidComponents.onVariants path as application variants: the compile, assets and jniLibs tasks are registered lazily per library variant, and the assets and native libraries are generated source directories of the variant. The host app consumes them like any Android library. Deletes the host-project lookup, the libraryVariants x applicationVariants cross-wiring, the merge<HostVariant>Assets.dependsOn edge, addFlutterDepsForModule, addCopyFlutterAssetsDependency, shouldConfigureFlutterTask(Project, Task) and buildModeFor(com.android.builder.model.BuildType). flutter.hostAppProjectName has no effect and logs a warning. The jniLibs copy is wired from the compile task provider, so its input directory is required in both copy tasks.
…er comments - CopyFlutterApksTask: state why caching is disabled (local copy; a cache entry would duplicate the APKs) and build both errors through one transformedApkError helper. - Trim comments and KDoc added by this PR to what the code does not already say.
…er-agent/flutter into agp-add-to-app-module # Conflicts: # packages/flutter_tools/gradle/src/main/kotlin/FlutterPlugin.kt # packages/flutter_tools/gradle/src/main/kotlin/FlutterPluginUtils.kt
Keep only what the code doesn't say: why library variants are not gated by the command line, why the copy task inputs are required, and what the tests guard. Restore PR 7's shouldCompileFlutterForVariant paragraph verbatim.
reidbaker
left a comment
There was a problem hiding this comment.
Please update the top of the pr to include a link for how to review only the changes intended in pr 8 while we wait for pr 7 to land. Something like this https://github.com/flutter/flutter/pull/193717/changes/33f39876b92a9e904a092375c141d6c4de2df62c..a6be16034c8a1a4a0456cd35194b5973cfd4dc75 would give the changes for 2 diffs, or if you can used stacked prs.
| * [FlutterPluginUtils.shouldConfigureFlutterTask] exists to prevent. Removing it is | ||
| * tracked by https://github.com/flutter/flutter/issues/109560, which also documents the | ||
| * AGP behavior that made it necessary. |
There was a problem hiding this comment.
Should this "hack be removed" it seems like the bug was a result of our seeing build breakages and not being able to modify our interactions with agp such that the expected behavior happens. Seee #109560 (comment)
If the "hack" should be removed should it happen as part of this pr, this pr stack or independently? Is the root cause still something that can happen with the migration in progress?
There was a problem hiding this comment.
Not in this PR. I couldn't reproduce either root cause on this stack.
Test setup: a scratch app on AGP 9.3.1 / Gradle 9.5.0 with two flavors, built with ./gradlew clean :app:assembleFlavoraRelease. With two tasks on the command line, the gate returns true for all 6 variants.
Results:
- Only the
FlavoraReleaseFlutter tasks were realized and run. lintVitalAnalyzeFlavoraReleaseran without any debug compile.
That's because task registration is lazy. Laziness removes both the AGP 4.0 lint dependency and the eager configuration described in the linked comment.
I didn't test a CMake/native flavor build (issuetracker 329132239) or the AGP 8.11.1 floor.
I suggest removing the gate in an independent PR after the stack lands, tracked by #109560. It changes app behavior and should be revertable on its own. Removing the gate also removes the LibraryVariant special case.
| * Library (add-to-app module) variants are never gated: the command line names a host | ||
| * task, and `matchingFallbacks` can map it to a module variant of any name. The tasks are | ||
| * registered lazily, so only the module variant the host consumes runs. |
There was a problem hiding this comment.
Rewritten in b8cd39b.
The command line names a host task (:app:assembleDemoStaging), and the host's matchingFallbacks choose the module variant. So the module can't tell from the task name which of its variants is needed.
All library variants are registered. Because registration is lazy, only the consumed one runs.
| project, | ||
| "assemble${FlutterPluginUtils.capitalize(variant.name)}" | ||
| ) | ||
| variant is LibraryVariant || |
There was a problem hiding this comment.
Maybe this comment is related to https://github.com/flutter/flutter/pull/193717/changes/f668780fd47caca13c03828f49d21572074825d6..a6be16034c8a1a4a0456cd35194b5973cfd4dc75#r4185324460 but why are library variants the only one that need this check and why does a pr about add to app have to be the one that modifies this code?
There was a problem hiding this comment.
Before this PR, module variants were gated through the host loop (FlutterPlugin.kt:404-407 on 33f3987):
applicationVariants.all → shouldConfigureFlutterTask(project, appAssembleTask) → map to a module variant by build mode.
This PR deletes that loop and routes library variants through onVariants, so it has to decide the gate for them.
shouldConfigureFlutterTask (FlutterPluginUtils.kt:352) matches the exact name or a Debug/Release/Profile suffix. So :app:assembleDemoStaging matches no module task. When I removed variant is LibraryVariant ||, the staging APK was missing AssetManifest.bin.
Application variants keep the gate because their task names do match.
| } | ||
| // The assets source set is expected to exist for application variants; fail loudly | ||
| // rather than silently building an APK without Flutter assets. | ||
| // The assets source set is expected to exist for application and library variants; |
There was a problem hiding this comment.
Are there other types of variants? if not then can we not specific a tautological list?
There was a problem hiding this comment.
Yes. gradle-api 9.1.0 has four Variant subtypes: Application, Library, DynamicFeature and Test.
FGP is only applied to app and library projects. The deferred-component template applies com.android.dynamic-feature without FGP.
I removed the list in b8cd39b.
| * Registers the [FlutterTask] (the `flutter assemble` invocation) for [variant], | ||
| * configured entirely from the public variant API. Application projects only; the | ||
| * add-to-app module path registers its own compile task in [addFlutterDepsForModule]. | ||
| * configured entirely from the public variant API. |
There was a problem hiding this comment.
Does "configured entirely from the public variant API." add any value to future maintainers? I dont think so.
There was a problem hiding this comment.
Agreed. In b8cd39b the KDoc is: Registers the [FlutterTask] (the flutter assemble invocation) for [variant].
|
|
||
| /** | ||
| * Per-ABI versionCodes and the copy into `build/outputs/flutter-apk/`. Library variants | ||
| * produce an AAR, so they need neither. |
There was a problem hiding this comment.
So they need neither what?
There was a problem hiding this comment.
Reworded in b8cd39b: "Configures the per-ABI versionCodes and the copy into build/outputs/flutter-apk/. Both act on APK outputs, which library variants don't have."
There was a problem hiding this comment.
This file has a lot of mocking per test. Is there a way to make individual tests easier to understand and reduce code duplication?
There was a problem hiding this comment.
d8f869e adds stubTaskRegistration, captureTaskConfiguration and setCommandLineTasks, and PR 8's three tests use them.
The tests from PR 6/7 repeat the same stubs at about 7 sites. I'll convert those in a follow-up after the stack lands, so this PR doesn't rewrite tests it didn't add.
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| @Timeout(Duration(minutes: 15)) |
There was a problem hiding this comment.
where in our stack is this value used? Why not rely on the default?
There was a problem hiding this comment.
It only repeated the default. packages/flutter_tools/dart_test.yaml sets timeout: 15m and says "we never set the timeouts in the tests themselves".
The file is now deleted (see the next reply).
There was a problem hiding this comment.
I am surprised this is not already an existing integration test. Are you sure there was not something close that could be modified to check the new integration behavior for warning about hostAppProjectName.
There was a problem hiding this comment.
Yes. devicelab module_host_with_custom_build_test already builds this fixture one task at a time, including assembleDemoStaging.
2efbd34 deletes the integration test and instead:
- adds a
qabuild type to the fixture; - adds a final devicelab section that runs
app:assembleDemoQawith-Pandroid.newDsl=true -Pandroid.compatibility.enableLegacyApi=false -Pflutter.hostAppProjectName=app.
The section checks for the warning, the Flutter assets and libapp.so (arm64, armeabi-v7a), and that no debug assets are present.
It runs presubmit on Linux, Mac and Windows (.ci.yaml:1104, 4486, 6630). Local run: success.
This also corrects my earlier reply (r4184409663): android_add_to_app_module_test no longer exists. The new devicelab qa section sets flutter.hostAppProjectName and checks the warning.
Explain why library variants skip the command-line gate, drop the application/library list from the assets comment, drop the 'public variant API' clause, and say what library variants lack in configureApplicationOutputs.
…m_build_test The devicelab test already builds the same host fixture one task at a time. Add a debuggable qa build type that falls back to the module's release variant, and a final section that builds it with android.newDsl=true and flutter.hostAppProjectName set. It checks the warning and that the APK has release Flutter artifacts. Delete android_add_to_app_module_test.dart, which duplicated that setup.
Add stubTaskRegistration, captureTaskConfiguration and setCommandLineTasks, and use them in the add-to-app onVariants tests.
| <String>[ | ||
| 'app:assembleDemoQa', | ||
| '-Pandroid.newDsl=true', | ||
| '-Pandroid.compatibility.enableLegacyApi=false', |
There was a problem hiding this comment.
https://gitgud.io/aosp/platform/tools/base/-/commit/2fa01f332fdf8c258e7822173aaeaaee93477575
I think this value has been replaced with a more specific one. Maybe it does not matter because you are setting the values towards using the new api.
There was a problem hiding this comment.
Right. That commit ("Deprecate android.compatibility.enableLegacyApi") moves ENABLE_LEGACY_API from FeatureStage.Supported to FeatureStage.Deprecated(VERSION_10_0) with /** This flag is subsumed by android.enableLegacyVariantApi. */.
In AGP 9.1.0, 9.1.1 and 9.3.1 (javap on BooleanOption), android.enableLegacyVariantApi is itself ApiStage.Removed(VERSION_9_0, "The android.enableLegacyVariantApi property has no effect, use android.newDsl instead"). Setting it on 9.3.1 only prints that warning. So the flag that matters is android.newDsl, which the test already sets.
In 9.3.1, ENABLE_LEGACY_API is read only by the old variant API classes (BaseVariantImpl, ApkVariantOutputImpl, MergedFlavor, OldVariantApiLegacySupportImpl, and VariantServicesImpl.newPropertyBackingDeprecatedApi/newProviderBackingDeprecatedApi). newDsl=true doesn't create those, so the flag was redundant.
I dropped it in 1366874. devicelab still passes, and the qa section still builds with newDsl=true overriding the fixture's newDsl=false.
| ```kotlin | ||
| create("staging") { | ||
| initWith(getByName("debug")) | ||
| isDebuggable = true // staging gets debug Flutter artifacts |
There was a problem hiding this comment.
why is isDebuggable deleted here?
There was a problem hiding this comment.
It was deleted on purpose, in 8c9a54d.
The text it illustrated said Flutter maps host build types to build modes using the debuggable flag. That mapping (buildModeFor(com.android.builder.model.BuildType), which read isDebuggable) is deleted in this PR. The mode comes from the module variant that matchingFallbacks selects, so the flag doesn't affect the Flutter artifacts.
It was also redundant in the snippet: initWith(getByName("debug")) already makes staging debuggable (BuildType.initWith: "Copies all properties from the given build type.").
The PR body shows the effect: a debuggable qa that falls back to release gets release Flutter artifacts (libapp.so, compileFlutterBuildRelease), and the devicelab qa section checks that.
| variant: Variant, | ||
| dslVersionCodes: DslVersionCodes | ||
| ) { | ||
| check(variant is ApplicationVariant) { |
There was a problem hiding this comment.
"which library variants don't have." and " check(variant is ApplicationVariant) {" then what looks like an error code seems backwards unless I misunderstand how check works.
There was a problem hiding this comment.
You read check correctly: it throws when the condition is false. The message described what it expected, not what went wrong, and sat next to a KDoc about library variants.
In 798ac29 the call site branches on variant is ApplicationVariant and the function takes an ApplicationVariant. The compiler enforces the type, so there is no runtime check or message left.
Behavior is unchanged. In an application project, onVariants comes from ApplicationAndroidComponentsExtension : AndroidComponentsExtension<ApplicationExtension, ApplicationVariantBuilder, ApplicationVariant>, so every variant there is an ApplicationVariant.
Branch on the variant type at the call site so the function receives an ApplicationVariant and needs no check().
…a section AGP 9.1 and 9.3 deprecate the option. Its consumers back the variant API that android.newDsl=true already removes.
There was a problem hiding this comment.
Code Review
This pull request migrates the Flutter Gradle Plugin's APK copying and per-ABI versionCode configuration to the modern Android Gradle Plugin (AGP) Variant API, removing deprecated legacy API dependencies. It introduces the CopyFlutterApksTask to copy and rename APKs using SingleArtifact.APK and BuiltArtifactsLoader, and the DslVersionCodes class to capture version codes during finalizeDsl, enabling compatibility with AGP's legacy API mode disabled. Additionally, add-to-app module configuration is simplified by removing host-project lookups and registering tasks lazily in onVariants. Unit tests, integration tests, and documentation are updated to align with these changes. No review comments were provided, so there is no feedback to address.
To review only PR 8 while #193693 is open: changes
f668780fd47..1366874099e.f668780fd47is PR 7's head, merged in by2c28d8f8245, so this range has no PR 7 changes. The link is updated on every push.Stacked on #193693. Review only the commits after
f668780fd47.PR 8 commits:
8c9a54d8297Unify add-to-app module wiring on the variant API2c28d8f8245Merge PR 7 headf668780fd47(conflicts resolved to PR 7's wording where PR 8 does not change the code)a6be16034c8Trim comments added by PR 8b8cd39bcf81Address review: clarify the variant gate and task registration comments2efbd345505Address review: check the add-to-app module in module_host_with_custom_build_testd8f869ec468Address review: share task registration stubs in FlutterPluginTest798ac295725Address review: take ApplicationVariant in configureApplicationOutputs1366874099eAddress review: drop android.compatibility.enableLegacyApi from the qa sectionDescription
This is PR 8 of 11 in the AGP 9.1.0 / public
gradle-apimigration stack (#180137, #166550).An add-to-app module (an Android library) is wired through the same
androidComponents.onVariantspath as an app. The module adds Flutter's assets and native libraries to its own variants, and the host app consumes them like any Android library. Flutter does not look up or configure the host project. With this PR, a host app with AGP 9'sandroid.newDsl=truebuilds a Flutter module from source; on33f39876b92it fails withCheck failed.while configuring:app.Breaking:
flutter.hostAppProjectNamehas no effect. Setting it logs a warning.Base:
reidbaker-agent:agp-apk-copy-versioncodeatf668780fd47(PR 7, #193693, open). When #193693 merges, this branch will mergemasterin.Agent authored details
Changes
Module variants on
onVariants(FlutterPlugin.ktaddFlutterTasks). For every variant, app or library,onVariantscallsregisterFlutterCompileTask,registerFlutterAssetTasksandregisterFlutterJniLibsTask. Only application variants then call the newconfigureApplicationOutputs(per-ABI versionCodes and the flutter-apk copy), which takes anApplicationVariant. There is no mid-lambdareturn@onVariants.Every module variant is configured.
shouldCompileFlutterForVariantreturns true for aLibraryVariant. The command-line check (shouldConfigureFlutterTask, Removeflutter.gradleshouldConfigureFlutterTaskhack #109560) compares the command line with the project's ownassemble<Variant>names, and a host task such as:app:assembleDemoStagingnever matches the module variant it consumes (debug, viamatchingFallbacks). A module has three variants: the template'sdebugandrelease, plus theprofilebuild type the plugin creates. It declares no flavors (templates/module/android/library_new_embedding/Flutter.tmpl/build.gradle.tmpl). The tasks are registered lazily, so a build runs only the module variant the host consumes.--dry-runon a host with flavordemoand build typesstaging(falls back todebug) andprod(falls back torelease):app:assembleDemoDebug,app:assembleDemoStagingcompileFlutterBuildDebug,copyFlutterAssetsDebug,copyJniLibsflutterBuildDebugapp:assembleDemoRelease,app:assembleDemoProdcompileFlutterBuildRelease,copyFlutterAssetsRelease,copyJniLibsflutterBuildReleaseBuild mode from the module variant.
registerFlutterCompileTaskreads the library variant'sbuildTypeand publicComponent.debuggable, so the mode follows the module variant the host consumes.jniLibs wired from the compile task provider.
registerFlutterJniLibsTasktakescompileTaskProviderand setsintermediateDirfromcompileTaskProvider.map { it.outputDirectory }. Thetasks.matching { it.name == … }dependency and thefindByNameprovider are gone. Both copy tasks are registered only together with their compile task, sointermediateDiris required (not@Optional) inCopyFlutterJniLibsTaskandCopyFlutterAssetsTask, and theirisPresentbranches are removed.flutter.hostAppProjectName.warnIfHostAppProjectNameIsSetreadsproject.providers.gradleProperty(…)(notrootProject.hasProperty) and logsWarning: The Gradle property 'flutter.hostAppProjectName' has no effect. Remove it from gradle.properties.Theflutter.hostAppProjectName=SampleAppline is removed fromdev/integration_tests/pure_android_host_apps/android_custom_host_app/gradle.properties, so devicelabmodule_custom_host_app_name_test(host project:SampleApp) checks that a host not namedappbuilds without the property.Deleted:
FlutterPlugin.kt: the host-project lookup, theappProject.afterEvaluate×libraryVariants.all×applicationVariants.allloop, themerge<HostVariant>Assets.dependsOnedge,addFlutterDepsForModuleandaddCopyFlutterAssetsDependency.FlutterPluginUtils.kt:shouldConfigureFlutterTask(Project, Task)andbuildModeFor(com.android.builder.model.BuildType). Both lost their last caller.Docs.
Migrating-Flutter-Gradle-Plugin-to-AGP-public-API.md: decision record 5 and "Features that must break" item 6 are rewritten.website-page-draft.md(publishing tracked in #193713): the add-to-app section is rewritten.stagingdebuggable build type gets debug artifacts (the module variant decides). It also said thattasks.getByPath(":flutter:copyFlutterAssetsDebug")fails with "Task with path … not found". That is false: in the scratch host below it returns aCopyFlutterAssetsTask.Tests.
FlutterPluginTestcases:debug,profileandrelease;hostAppProjectNamewarning, with no host lookup, and no warning when it is unset.stubTaskRegistration,captureTaskConfiguration,setCommandLineTasks).module_host_with_custom_build_testgets a final section. The host fixture adds a build typeqa(debuggable, falls back torelease). The section runsapp:assembleDemoQawithandroid.newDsl=trueandflutter.hostAppProjectName=app. It checks that the output has the warning, and thatapp-demo-qa.apkhas the Flutter assets andlibapp.sofor arm64-v8a and armeabi-v7a, and no debug assets. The existing sections already checkapp:assembleDemoStaging(debug artifacts).Audit resolution
PR 8 draft audit:
FlutterPlugin.kt:549-553. Unit testonVariants wires the jniLibs copy to the output of the variant's compile task.return@onVariantsonVariants(:329-350) calls helpers; app-only wiring is inconfigureApplicationOutputs(:647).dependsOn:497-530) or the jniLibs copy (:536-560).rootProjectread; fixture propertyshouldConfigureFlutterTask(Project, Task)deleted.providers.gradlePropertyat:665. Fixture line removed.PR 7 draft audit: its four items were resolved in #193693. The stale "registered in
applicationVariants" KDoc it named has no counterpart here; theregisterFlutterCompileTaskKDoc names no project type.Why removing the deleted code is safe
com.android.build.gradle.LibraryExtension.libraryVariants,AbstractAppExtension.applicationVariants,BaseVariant.mergeAssetsProviderandBaseVariantOutput.processResourcesProvider. AGP does not register those extensions withandroid.newDsl=true, which is why33f39876b92fails withCheck failed.in the hostafterEvaluateblock that looks upLibraryExtension. Its replacements (LibraryVariant,Component.debuggable,Sources.assets/jniLibs.addGeneratedSourceDirectory) are publiccom.android.build.apiAPIs at the stack's AGP 8.11.1 floor (Component.getDebuggablechecked withjavapon gradle-api 8.11.1).hostAppProjectNameusers: none.git grep hostAppProjectNamehits only this PR's code, tests and docs, plus an unrelated iOSXcodeProject.hostAppProjectNamein the tool. The templates,include_flutter.groovy,module_plugin_loader.gradleand devicelab do not read it. devicelabmodule_custom_host_app_name_test(host project:SampleApp) passes without the fixture property.com.android.builder.model.BuildTypeandshouldConfigureFlutterTask(Project, Task)have no remaining references.Removed comments, docstrings and tests
TODO(gmackall)comments (#166550) onaddFlutterDepsForModule; KDoc onaddCopyFlutterAssetsDependencyshouldConfigureFlutterTask(Project, Task)andbuildModeFor(ModelBuildType)flutterCompileTaskNameKDocregisterFlutterJniLibsTask, and the@OptionalKDoc and "no Flutter build" comment inCopyFlutterJniLibsTaskgradle_libapp_so_packaging_test"app:assembleAndroidTest builds when no Flutter compile task is configured" still passes.@OptionalKDoc onCopyFlutterAssetsTask.intermediateDir(it kept@Optionalfor the module migration)FlutterPluginUtilsTest:buildModeFor returns profile if the BuildType has name profile,buildModeFor returns debug if the BuildType is debuggable,buildModeFor returns release if the BuildType is not debuggable and not named profilebuildModeFor with a name and debuggable flag prefers the profile name over debuggabilitycovers the same cases.FlutterPluginUtilsTest: fourshouldConfigureFlutterTasktests used a mockedTaskStringoverload.CopyFlutterAssetsTaskTest:clears the destination directory when there is no flutter build for the variantremoves staged assets that the flutter build does not produce, which keeps the stale-file check.a6be16034c8): thePROP_HOST_APP_PROJECT_NAMEKDoc; theregisterFlutterJniLibsTaskKDoc sentence naming its compile task; the "An application project only has application variants." comment above thecheck; restatements in the KDoc ofshouldCompileFlutterForVariant(PR 7's paragraph restored verbatim),registerFlutterCompileTask,configureApplicationOutputs,warnIfHostAppProjectNameIsSetand bothintermediateDirs; test helper KDocs and integration test comments; migration doc item 6f668780fd47: 85 → 39.packages/flutter_tools/test/integration.shard/android_add_to_app_module_test.dart(added by this PR, then deleted per review,2efbd345505)qacheck moved into devicelabmodule_host_with_custom_build_test, which builds the same fixture. Itsstagingcheck duplicated the devicelab staging section, except forandroid.newDsl=true. The devicelab task runs presubmit on Linux, Mac and Windows (.ci.yaml), like the deleted test.b8cd39bcf81): the library paragraph of theshouldCompileFlutterForVariantKDoc, the assetsGradleExceptioncomment, theregisterFlutterCompileTaskandconfigureApplicationOutputsKDocscheck(variant is ApplicationVariant)that PR 7 added in the apponVariantspath, moved by this PR intoconfigureApplicationOutputs(798ac295725)variant is ApplicationVariant, and the function takes anApplicationVariant, so the compiler enforces the type. In an application project every variant is anApplicationVariant, so the APK wiring runs for the same variants.-Pandroid.compatibility.enableLegacyApi=falsein the devicelabqasection (1366874099e)Deprecated(VERSION_10_0). Its consumers back the variant API thatandroid.newDsl=trueremoves.Behavioral and compatibility notes
flutter.hostAppProjectNamehas no effect (breaking). It logs a warning and names no removal milestone. Its only use was the host lookup.The Flutter build mode follows the module variant the host consumes. A host
debug/profile/releaseconsumes the module variant of the same name. A custom host build type gets the module variant itsmatchingFallbacksselect. With a debuggableqathat falls back torelease, built as the only task, the APKs contain:flutter_assetslibapp.so33f39876b92(newDsl=false)compileFlutterBuildDebug(not packaged)compileFlutterBuildReleaseA host
assemble<Variant>AndroidTestrun on its own runs the module'sflutter assemblefor that variant.--dry-runof:app:assembleDemoDebugAndroidTestlists:flutter:compileFlutterBuildDebugwith this PR, and onlycopyJniLibsflutterBuildDebugon33f39876b92. This is a cost, accepted because the module cannot map host task names to its own variants.Module assets are a generated assets source directory. The deleted code copied them into the module's merged-assets output after
mergeAssets, and made every build re-runclean<MergeAssetsTask>. Collisions resolve by source-set priority, as for apps since PR 6.copyFlutterAssets<V>in a module is aCopyFlutterAssetsTask, not aCopy. Lookups by name still work; lookups typed asCopyfail.Related open work: #191703 reports an NPE in
getLegacyAndroidExtensionwithnewDsl=true. That function was removed earlier in the stack, and this PR removes the next failure on that path. A module with plugins onnewDsl=trueis not tested here. No conflict with #193682 or #193610 (gradle_errors.dart); this PR changes no message that the tool matches. #184409 asks for separate library and app logic inaddFlutterTasks; this PR sharesonVariantsand splits only the app outputs.Integration test coverage of the changed paths
newDsl=true, debuggable custom build type onrelease,hostAppProjectNamewarningmodule_host_with_custom_build_test,app:assembleDemoQasectionmodule_host_with_custom_build_test(other sections;app:assembleDemoStagingneeds the ungatedLibraryVariant),build_android_host_app_with_module_sourceapp, withouthostAppProjectNamemodule_custom_host_app_name_testflutter build aar) and AAR hostbuild_aar_module_test,build_android_host_app_with_module_aar;android_obfuscate_test,android_plugin_new_output_dir_testgradle_libapp_so_packaging_test,flutter_build_apk_split_per_abi_test,android_gradle_asset_merging_test,android_run_flutter_gradle_plugin_tests_testTests run locally (macOS, JDK 17)
On the head (
1366874099e):./gradlew test --rerun-tasksinpackages/flutter_tools/gradle: 33 suites, 274 tests, 0 failures..editorconfigand baseline: clean.dart formatanddart analyze --fatal-infosonmodule_host_with_custom_build_test.dart: clean.module_host_with_custom_build_test:success. Theapp:assembleDemoQasection ran./gradlew app:assembleDemoQa -Pandroid.newDsl=true -Pflutter.hostAppProjectName=appand logged theflutter.hostAppProjectNamewarning.On
d8f869ec468:./gradlew test --rerun-tasksinpackages/flutter_tools/gradle: 33 suites, 274 tests, 0 failures..editorconfigand baseline: clean.dart formatanddart analyze --fatal-infosonmodule_host_with_custom_build_test.dart: clean.module_host_with_custom_build_test:success. Theapp:assembleDemoQasection logged theflutter.hostAppProjectNamewarning.On
a6be16034c8(the merge and the trim):./gradlew testinpackages/flutter_tools/gradle: 33 suites, 274 tests, 0 failures..editorconfigand baseline: clean.dart formatanddart analyze --fatal-infoson the changed Dart files: clean.android_add_to_app_module_test(deleted in2efbd345505): passes.module_custom_host_app_name_test(fixture withoutflutter.hostAppProjectName):success, and the log has nohostAppProjectNamewarning.On
8c9a54d8297(before the merge of PR 7's review changes and the comment trim):android_add_to_app_module_test(1),android_obfuscate_test(2),android_plugin_new_output_dir_test(1),gradle_libapp_so_packaging_test(4),flutter_build_apk_split_per_abi_test(4),android_gradle_asset_merging_test(4),android_run_flutter_gradle_plugin_tests_test(2).android_add_to_app_module_teston33f39876b92: fails withCheck failed.. Withvariant is LibraryVariant ||removed: fails with "does not contain 'assets/flutter_assets/AssetManifest.bin'".bin/test_runner.dart test --exit, allsuccess:module_host_with_custom_build_test,module_custom_host_app_name_test,build_android_host_app_with_module_source,build_aar_module_test,build_android_host_app_with_module_aar.assembleDemoStaginghaskernel_blob.binand nolibapp.so;assembleDemoReleasehaslibapp.sofor arm64-v8a, armeabi-v7a and x86_64.android.compatibility.enableLegacyApi=false, and withandroid.newDsl=trueadded.Pre-launch Checklist
///).