Skip to content

Add AGP public-API migration docs (contributor doc + breaking-change page draft) - #1

Closed
reidbaker-agent wants to merge 147 commits into
masterfrom
agp-api-doc
Closed

reidbaker-agent wants to merge 147 commits into
masterfrom
agp-api-doc

Conversation

@reidbaker-agent

@reidbaker-agent reidbaker-agent commented Jul 22, 2026 •

Copy link
Copy Markdown
Owner

Phase 1 of 11 of the AGP public-API migration.

Phase P0 of the Flutter Gradle Plugin migration to the AGP public API
surface (flutter#180137, flutter#166550): the contributor
migration record (replacement map, decision records, phase map,
revert-window table) and the draft of the user-facing breaking-change
page to be published to docs.flutter.dev before the newDsl flip reaches
beta.

Revert-safe: always.

CI must run the FGP unit tests (the Kotlin suite in packages/flutter_tools/gradle could not run in the delivery sandbox: dl.google.com returns 403, so AGP artifacts do not resolve).

Mairramer and others added 3 commits July 22, 2026 06:12
…er#187992)

Related to flutter#21039


## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This change mostly removes unused imports and fixes the linter warnings
about asserts

<img width="422" height="57" alt="Screenshot 2026-07-10 at 17 47 51"
src="https://github.com/user-attachments/assets/dda17237-27d5-4280-b632-9cadf3de12f6"
/>
<img width="333" height="66" alt="Screenshot 2026-07-10 at 17 36 03"
src="https://github.com/user-attachments/assets/18ddae56-7777-4aa9-a5db-12f3b93e0bbf"
/>
<img width="444" height="440" alt="Screenshot 2026-07-10 at 17 44 57"
src="https://github.com/user-attachments/assets/3690f477-c0cf-438e-85c3-03bf0da0fc76"
/>
<img width="427" height="273" alt="Screenshot 2026-07-10 at 17 34 16"
src="https://github.com/user-attachments/assets/3be1122e-a340-470d-beb9-e75785f50344"
/>


## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This is no longer updated with a workflow and a solution requires infra
team work. Removing for now

See flutter#178913
cbracken and others added 25 commits July 22, 2026 16:27
The `pub package cache` step in composite-flutter-setup keys its cache
on a hash of the pubspec.yaml files found under dev/, examples/, and
packages/, but omits the root workspace pubspec.yaml. The root pubspec
pins the versions of all transitive dependencies, so a pub roll that
only touches the root, leaves the hash, and therefore the hash key,
unchanged. This is exactly what happens on pub package rolls like
flutter#189760.

When that happens the cache still hits and restores a stale pubspec.lock
over the freshly checked-out one. At that point, the following `flutter
update-packages` then fails when run with `--enforce-lockfile`, since
the lock file we just restored from cache no longer matches the pinned
versions in the checked-out root pubspec.yaml, which breaks the Tree
Analyze step tree-wide until the cache is manually invalidated.

We now include the root pubspec.yaml in the hash so that a packages only
roll changes the cache key, forcing a fresh package resolve rather than
restoring a stale lock.

Fixes: flutter#189825

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->


## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: John "codefu" McDole <john@mcdole.org>
…uest (flutter#187957)

Fixes flutter#85941

When a user traverses focus nodes directionally (e.g. using `up`, `down`
arrow keys), we maintain a history stack of visited nodes (called
`policyData`). This allows us to avoid
[hysteresis](https://en.wikipedia.org/wiki/Hysteresis) when a user
switches direction (i.e. switching from `down` to `up`) - meaning, the
forward traversal path and the reversed traversal path should match.

However, before this change, we were not detecting when a focus request
occurred due to some outside event (e.g. a direct focus request from a
tap on the screen). That means when a user switched direction, we would
include the node they had tapped on in the history stack, and
unexpectedly visit it.

We now clear the stack (see method `propagateFocusRequest`) if a node is
focused on outside of a directional navigation event.

**Before:**

<img width="454" height="656" alt="before"
src="https://github.com/user-attachments/assets/26e3cdd2-2f39-4dc8-9616-4f21d4afcc52"
/>

**With fix:**

<img width="454" height="656" alt="fixed"
src="https://github.com/user-attachments/assets/0e795e0c-8e07-4422-beed-f371407b4ae6"
/>


## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Closes flutter#162226.

Sadly win32 doesn't allow `\0` characters inside the `CF_UNICODETEXT`
clipboard. To prevent it, I replaced the null terminator with the
`\uFFFD` (replacement character:
https://www.compart.com/en/unicode/U+FFFD).
I replaced the string type to a string view to also store the size on
the way so it doesn't break on the way if there are null terminators.

~~Currently a draft since I don't have tests yet.~~

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Temporary workaround for
flutter#189876.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…when no expansion is needed, and remove 1-pixel roundrect to rect simplification (flutter#189808)

Fixes flutter#189807

See the issue for more context.

Adds a unit test that fails without this change, and passes with this
change.

Verified the demo app in the issue renders properly with this change.

From the issue:

## Root cause and fix


[Rect::ExpandToMinTransformedSize](https://github.com/flutter/flutter/blob/1c8b3088238220102df66761685f3a4718b5aa15/engine/src/flutter/impeller/geometry/rect.h#L705)
always constructs a new expanded rectangle from the input Rect from its
center point and half-extents.

If the input rectangle is already large enough and does not need
expansion, this should return an identical rectangle. The returned
rectangle is equality-checked against the input in
[Canvas::DrawRoundRect](https://github.com/flutter/flutter/blob/1c8b3088238220102df66761685f3a4718b5aa15/engine/src/flutter/impeller/display_list/canvas.cc#L1129)
to determine whether expansion happened. That code assumes that if the
output does not equal the input, pixel-expansion happened, which means
that the rounded rect had sub-pixel dimensions and can be safely drawn
as a non-rounded rectangle.

The issue is that for certain cases, particularly with non-integer
sizes, ExpandToMinTransformedSize returns a different rectangle even if
no expansion happened. This is due to small floating point imprecisions
when constructing the new rectangle using the input rectangle's center
and half-extents.

To fix this, ExpandToMinTransformedSize should not construct a new
rectangle unless expansion is actually needed.

## Removal of 1-pixel roundrect to rect simplification

This PR also removes the 1-pixel roundrect to rect simplification in
`Canvas::DrawRoundRect`. As described in
flutter#189807 (comment),
this optimization resulted in slightly different colors at the tips of
thin roundrects.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…89815)

Now that DisplayLinkManager is injected in nearly all use-cases and the
`.shared` singleton is used at exactly 3 remaining call-sites, marks
`.shared` and `init()` as `@MainActor` now that it's safe to do so.

`DisplayLinkManager.init()` has always required betin called on the main
thread since it reads `UIScreen.main`/`Bundle.main`, but that was only
enforced by a runtime assert. which compiles out in most release
configruations. The Swift compiler can now enforce a static, checkable
contract instead. Actor-isolation checking is enforced in Swift 5.5+
regardless of strict-concurrency level or language mode, so this takes
should take effect immediately given our current Swift 5 language
mode/default concurrency checking not gated behind a migration.

I've left the manual `assert(Thread.isMainThread, ...)` in place for now
given the existing Obj-C use in `FlutterViewController` and
`FlutterMetalLayer`. If we do eventually remove it, we should ensure
that the runtime itself is enforcing this runtime behaviour first --
this is dependent on SDK version.

I've also left the internal testing initializer non-isolated: it doesn't
touch `UIScreen`/`Bundle.main`, so it has no main-thread requirement,
and leaving it alone keeps the two tests that use it compiling
unchanged.

`DisplayLinkManagerTest.swift`'s `testSharedInstanceReturnsAValidValue`
and `testDisplayConfigurationNotificationsAreHandledWithoutCrashing`
both call `.shared` directly, so we needed to mark the test class
`@MainActor`. XCTest already runs these on the main thread, so this is a
no-op but makes the compiler (which doesn't know about XCTest's
implementation) happy.

No semantic changes to tests because there's no semantic change to the
logic, and this is enforced by the complier itself.

Issue: flutter#175879
Issue: flutter#181684


## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This adds a post-processing pass to `complie_commands.json` that
synthesizes the Swift entries that can be understood by SourceKit LSP
and wires up the editor config needed to pick them up.

GN's `--export-compile-commands` only understands the built-in
`cc`/`cxx`/`objc`/`objcxx` tool types, and doesn't yet have built-in
support for injecting `swiftc` lines, so our custom `swift` tool (which
invokes `swiftc.py`) never gets an entry there, meaning Swift code in
the iOS and macOS embedders isn't indexed by SourceKit LSP and other
tooling that reads that file.

Since GN's own compdb export omits the swift targets, `_postGn()` now
shells out (once) to `ninja -t compdb` for the full compilation database
(and falls back to the existing `compile_commands.json` on disk if that
fails), then runs it through `expandSwiftcCommands`, which turns each
`swiftc.py`-wrapped entry into one or more native `swiftc` invocations,
one per compiled Swift file, with relative paths resolved to absolute
against the entry's `directory`.

We drop `-isystem` and `-Dkey=value` flags since that's what `swiftc.py`
does; swiftc only accepts boolean -D defines not key=value flags.

This scans the raw ninja output directly rather than decoding all of
`compile_commands.json`, which can run past 20MB and is too slow to
parse wholesale in Dart; only the small handful of matched `swiftc.py`
entries get `jsonDecode`d -- fewer than 10 lines.

This also wires up `.sourcekit-lsp/config.json` and the
`swift.sourcekit-lsp.supported-languages` setting in
`engine.code-workspace`/`engine-workspace.yaml` so that VS Code's Swift
extension correctly picks up the generated compdb.

Fixes flutter#185741

## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
)

Adds a skill for generating a "what's new" for the flutter engine across
branches. This skill wasn't able to generate the information directly
needed for a blog post but it was informative to writing highlights for
a blog post. It's probably worth checking this in and trying to refine
it further in the future.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…r#189883)

https://dart.googlesource.com/sdk.git/+log/1e65011ee004..9258584f98b8

2026-07-22 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-53.0.dev
2026-07-22 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-52.0.dev
2026-07-22 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-51.0.dev
2026-07-22 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-50.0.dev
2026-07-22 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-49.0.dev
2026-07-21 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-48.0.dev
2026-07-21 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com
Version 3.14.0-47.0.dev

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/dart-sdk-flutter
Please CC dart-vm-team@google.com,jsimmons@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
…lutter#187202)

- Listen to device log reader before VM Service connection in both
`flutter drive` and `flutter run` (Resident Runner) to ensure logs are
captured even if startup fails.
- Wrap VM Service connection in a try-catch and apply a configurable log
flush delay (default 500ms) to allow buffered logs to arrive before
rethrowing.
- Make the delay configurable (`logFlushDelay`) in
`FlutterDriverService` and `FlutterDevice`, defaulting to
`Duration.zero` in tests to keep them fast.
- Add tests in `resident_runner_test.dart` and update
`drive_service_test.dart` to verify the behavior.

Fixes: flutter#162087

## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Ben Konyi <bkonyi@google.com>
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Closes flutter#166309.

Windows only captured mouse input for primary-button drags. As a result,
drag gestures using middle, secondary, or X buttons received a pointer
remove when leaving the client area.

Capture is now enabled for every supported mouse button and released
only
after the last pressed mouse button is released.

Also tested on my universal flutter input demo:
https://github.com/CodeDoctorDE/flutter-input-demo/tree/e448c2cf42981d9c8b5186a7e43d1b82a0239619.

~~Currently in draft since I cannot have 2 pull requests open at the
same time.~~

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Matthew Kosarek <matt.kosarek@canonical.com>
flutter#189461)

## Description

On macOS, `AndroidStudio.allInstalled()` calls `mdfind` via `runSync` to
locate Android Studio installations outside standard locations. When
Spotlight (`mds_stores`/`mdworker`) is unresponsive or re-indexing,
`mdfind` hangs indefinitely and blocks `flutter doctor` and `flutter
daemon`.

This PR wraps `mdfind` in a shell execution with a 3-second process
timeout and killer subshell cleanup to prevent `flutter doctor` and
`flutter daemon` from hanging indefinitely. If the query times out or
fails, `_allMacOS` gracefully falls back to standard candidate paths.

Fixes flutter#189177

## Tests

- Added `installation detection on MacOS gracefully handles unresponsive
Spotlight query (issue flutter#189177)` unit test in
`packages/flutter_tools/test/general.shard/android/android_studio_test.dart`.
Work towards dart-lang/sdk#59226

The analyzer will start reporting cases where a super parameter could be
used, and the type of the supar parameter is tightened in the subclass
constructor. This is still a perfectly valid super parameter use case.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.


<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…89890)

Roll Skia from 5e183e5aeac5 to 3424966b8a2b (33 revisions)

https://skia.googlesource.com/skia.git/+log/5e183e5aeac5..3424966b8a2b

2026-07-22 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll
Dawn from 4527b42f1a95 to 63af03bd26e2 (8 revisions)
2026-07-22 michaelludwig@google.com Revert "[graphite] Trace more
DrawPass details"
2026-07-22 robertphillips@google.com Suppress failure cases for new
TestManyStopLinearHardstopsGanesh test
2026-07-22 arthursonzogni@chromium.org Disable partition_alloc on
Mac/iOS when using Xcode clang
2026-07-22 egdaniel@google.com [ganesh] Fully clear initial stencil bits
when stencil clear is a draw
2026-07-22 michaelludwig@google.com [graphite] Only use
CompressedPaintersOrder to stop layer search
2026-07-22 sergiog@microsoft.com [rust bmp] Move rust bmp out of
experimental
2026-07-22 thomsmit@google.com [graphite] SparseStrips SIMD coverage
improvements
2026-07-22 egdaniel@google.com Make sure partition alloc is disabled on
all clang mac names.
2026-07-22 michaelludwig@google.com [viewer] Avoid fLastImage polluting
Graphite caches
2026-07-22 robertphillips@google.com [ganesh] Skip resolve/mipmap step
on flush failure
2026-07-22 michaelludwig@google.com [graphite] Trace more DrawPass
details
2026-07-22 helmut@januschka.com [ganesh] Add many-stop analytic gradient
colorizer
2026-07-22 kjlubick@google.com Fix ganesh_native_vulkan target
2026-07-22 michaelludwig@google.com [skif] Request expected child output
for Magnifier
2026-07-22 michaelludwig@google.com [tracing] Add TRACE_COUNTER1_ALWAYS
variant
2026-07-22 jiawei.shao@intel.com Compare the return value of
`GetLimits()` with `wgpu::Status::Success`
2026-07-22 skia-autoroll@skia-public.iam.gserviceaccount.com Roll
vulkan-deps from 218432abf71f to a5843ef093d3 (2 revisions)
2026-07-22
recipe-mega-autoroller@chops-service-accounts.iam.gserviceaccount.com
Roll recipe dependencies (trivial).
2026-07-22
recipe-mega-autoroller@chops-service-accounts.iam.gserviceaccount.com
Roll recipe dependencies (trivial).
2026-07-22 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE
from 80d793462953 to 3d3c181bdcf2 (7 revisions)
2026-07-22 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia
Infra from b8df33bbc301 to ed73bb996e6d (15 revisions)
2026-07-22 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn
from 7c60d39b65ee to 4527b42f1a95 (3 revisions)
2026-07-22
recipe-mega-autoroller@chops-service-accounts.iam.gserviceaccount.com
Roll recipe dependencies (trivial).
2026-07-22
recipe-mega-autoroller@chops-service-accounts.iam.gserviceaccount.com
Roll recipe dependencies (trivial).
2026-07-22 thomsmit@google.com [ganesh][gl] ARM FBO query workaround
2026-07-21 michaelludwig@google.com [tracing] Remove TRACE_COUNTER2;
implement counters in SkPerfettoTrace
2026-07-21 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll
ANGLE from d6247827bfd0 to 80d793462953 (6 revisions)
2026-07-21 michaelludwig@google.com [graphite] Add BoundsFlags and
adjust test result names
2026-07-21 kjlubick@google.com Add sanitization proc to
SkTypeface::MakeDeserialize
2026-07-21 skia-autoroll@skia-public.iam.gserviceaccount.com Roll
vulkan-deps from f7e4835de105 to 218432abf71f (2 revisions)
2026-07-21 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll
Dawn from 1b6954523e35 to 7c60d39b65ee (6 revisions)
2026-07-21 fmalita@google.com Deprecate SkPath::updateBoundsCache

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/skia-flutter-autoroll
Please CC jlavrova@google.com,jsimmons@google.com,kjlubick@google.com on
the revert to ensure that a human
is aware of the problem.

To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry
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

...
…#189282)

removes the prints that were used to track
flutter#172636
the PR that added the prints
flutter#174073

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Ben Konyi <bkonyi@google.com>
…... (flutter#189898)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter
Please CC jsimmons@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
…9901)

https://skia.googlesource.com/skia.git/+log/3424966b8a2b..1d8bf9270d8c

2026-07-23 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia
Infra from ed73bb996e6d to 7a6f0a35a522 (13 revisions)
2026-07-23 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn
from 63af03bd26e2 to 85891e8dcf47 (6 revisions)
2026-07-23 skia-autoroll@skia-public.iam.gserviceaccount.com Roll
vulkan-deps from a5843ef093d3 to b65fca8cfc87 (6 revisions)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/skia-flutter-autoroll
Please CC jlavrova@google.com,jsimmons@google.com,kjlubick@google.com on
the revert to ensure that a human
is aware of the problem.

To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry
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
This is a prototype branch for moving `WindowManager` outside of
`WidgetsApp`.

Our current approach where first window is "blessed" and other windows
are anchored inside first window hierarchy is causing multiple issues:
- Only the first window has navigator
- Secondary windows focus zones are inside primary window focus zone so
it is always focused.
- Widget inspector only works in primary window

In general there is no reason for one window to be special. Normally for
a desktop application all windows should be equal. The closest we can
get to this is to give each top level window its own
Widgets/MaterialApp. While this duplicates some elements that should
normally be shared, arguably it behaves better than doing what we do
right now.

Ideally we'd want to split the App widget into shared and per window
parts, but that will be a much bigger change.

With this branch the top level Dialog/Regular window have each their own
MaterialApp widget and separate focus trees, solving the issues above.

`Popup` and `Tooltip` window work and are anchored at proper place in
window hierarchy (they should not be top level window). However we might
want to consider a convenience Widget to anchoring these instead of
using `ViewAnchor` + `View`.

Screenshot of example app running in this mode - notice the Debug banner
and widget inspector buttons in each window.

<img width="900" height="800" alt="Screenshot 2026-07-01 at 5 48 13 PM"
src="https://github.com/user-attachments/assets/bbb6e646-e9d8-4618-9702-19afe0749b11"
/>
…suite (flutter#189920)

This test is failing when run with today's randomized order seed.

See flutter#189919
…flutter#187201)

Fixes: flutter#175968 

## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

---------

Co-authored-by: Reid Baker <reidbaker@google.com>
## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
flutter#189460)

Add `.dart_tool/package_config.json`, `pubspec.yaml`, and
`.flutter-plugins-dependencies` (optional) to
`WebEntrypointTarget.inputs`, and
`{BUILD_DIR}/web_plugin_registrant.dart` to
`WebEntrypointTarget.outputs`.

Previously, `WebEntrypointTarget` only declared `{BUILD_DIR}/main.dart`
in `outputs` and its own source file in `inputs`. When plugins were
added or removed between consecutive `flutter build web` invocations,
`FlutterBuildSystem` evaluated `WebEntrypointTarget` as up-to-date,
skipping target execution and leaving `web_plugin_registrant.dart`
stale.

Fixes flutter#189128
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

Related: flutter#185924 

I have ensured that Flutter commands do not throw errors even in
projects without `Runner.xcworkspace`, such as those that have migrated
to SwiftPM.

Some migration processes checked for the existence of a workspace, but
these do not read or write to the workspace directory and function
correctly even if it is absent. While the exact intent is unclear, it is
likely that they were checking whether Cocoapods was included in the
project.

Also, it was causing an error in `buildXcodeProject` by not passing
scheme and BUILD_DIR as arguments when the workspace did not exist .

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Fix flutter#176657
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

This PR can improve app startup time for impeller+GLES on low-end
devices.
flutter#180022 has provided solution for
impeller + vulkan.

Impeller+GLES has a special case: resource loading cannot be arbitrarily
placed on other threads; it needs to be done on the I/O thread because
this thread shares the context with the GPU thread. Therefore, this PR
introduces the I/O task runner into PipelineCompileQueueGLES. However,
since the I/O task runner may handle other tasks, we cannot put all jobs
into the I/O thread at once. My current solution is to wait for the
previous job to finish before putting the next one into the I/O thread.


Main changes:
1. Introduce fml::RefPtr<fml::TaskRunner> into PipelineCompileQueueGLES.
2. Extract new class PipelineCompileQueueVulkan for vulkan, because the
runners are on different threads.


## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Jason Simmons <jsimmons@google.com>
Parses `android.useAndroidX` from `gradle.properties` instead of using a
raw substring match.

This avoids false positives from commented-out lines such as
`#android.useAndroidX=true`, and false negatives for valid Gradle syntax
such as `android.useAndroidX = true`.

This PR intentionally keeps the change scoped to property parsing and
does not change the broader behavior for projects that omit the property
entirely.

Part of flutter#188306

## Tests

```console
./bin/flutter test packages/flutter_tools/test/general.shard/android/gradle_test.dart
```

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`),
or this change does not require documentation updates.
- [x] I added new tests to check the change I am making.
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported, or this change is not a breaking change.
- [x] All existing and new tests are passing.

---------

Co-authored-by: jesswrd <jesswon@google.com>
cbracken and others added 9 commits July 31, 2026 08:53
…lutter#190330)

flutter#184501 updated accessibility
role mapping such that read-only text fields are mapped to
`ax::mojom::Role::kTextField`. On macOS, read-only text fields are
intentionally treated as static text. Because of the role change, the
macOS embedder incorrectly instantiated `FlutterTextPlatformNode` for
read-only text fields, leading to detached accessibility elements and
test crashes.

This updates the macOS platform node delegate to only instantiate a
FlutterTextPlatformNode when the target text field is actually editable
and not read-only or disabled. We now explicitly return read-only text
fields as standard static text elements. This matches current behaviour
but makes it explicit in the platform node delegate for macOS.

We're also now calling loadView on the viewController in tests. In a
running app, the view controller will always be loaded, so this better
approximates reality in the tests... and avoids bugs such as those
caught in flutter#184501.

This should allow us to reland
flutter#184501.

Issue: flutter#184559

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->


## Pre-launch Checklist

- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Migrates the `platform_channel_swift` example to import material_ui.

Related to flutter#190093.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
This flag was used to experiment with Dart GC performance. But it is not
actively being used and is no longer functioning as intended in Dart.

The flag was causing issues in recent Dart SDK rolls (see
flutter#190266)
…swapchain must be recreated due to a size change (flutter#190116)

KHRSwapchainVK::AcquireNextDrawable was calling vkAcquireNextImageKHR
regardless of whether the KHRSwapchainImplVK's size matched the current
size of the KHRSwapchainVK. If there was a size change, then the
resulting image would never be presented, which can cause resource leaks
even after the old swapchain is destroyed.

This PR avoids the call to KHRSwapchainImplVK::AcquireNextDrawable and
vkAcquireNextImageKHR if there is a size mismatch.

Fixes flutter#190114
…0347)

https://skia.googlesource.com/skia.git/+log/dcbd015c9646..7ef86a5b0eb9

2026-07-31 skia-autoroll@skia-public.iam.gserviceaccount.com Roll
vulkan-deps from 4ffddf5fb2e7 to 9b3fec1aec6c (14 revisions)
2026-07-31 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE
from 22ba45a57477 to 0e5d32f40590 (9 revisions)
2026-07-31 skia-autoroll@skia-public.iam.gserviceaccount.com Roll
debugger-app-base from 8f7ec5882f46 to 2d7debe40c61
2026-07-31 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia
Infra from 7f1c4bcf56a3 to e5a5eb98eb1c (9 revisions)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/skia-flutter-autoroll
Please CC aaclarke@google.com,bwils@google.com,kjlubick@google.com on
the revert to ensure that a human
is aware of the problem.

To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry
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
flutter/packages@7d17fc8...5351d8c

2026-07-30 katelovett@google.com [material_ui, cupertino_ui] Add
migration bridge utilities (flutter/packages#12314)
2026-07-30 269567208+reidbaker-agent@users.noreply.github.com Enforce
scoped validation tools in AGENTS.md with file-based trap evals
(flutter/packages#12297)
2026-07-30 engine-flutter-autoroll@skia.org Manual roll Flutter from
c83f80b to 2a230d1 (6 revisions) (flutter/packages#12325)
2026-07-30 engine-flutter-autoroll@skia.org Manual roll Flutter from
0f02463 to c83f80b (7 revisions) (flutter/packages#12318)
2026-07-30 kirill.webmail@yandex.com [camera_android_camerax] Prefer
higher resolution for max preset (flutter/packages#11956)

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 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
…ere added (flutter#190262)

ContentContext tries to create the most commonly used shaders first. But
previously the PipelineCompileQueue was using an unordered map to store
the shader compilation jobs, which made it iterate through the jobs in
arbitrary order.

This means that the queue may not build the most needed shaders earliest
in the background. If these shaders are not built before the raster
thread needs them, then the raster thread will need to spend time
building them on demand.

This PR changes PipelineCompileQueue to use an Abseil linked hash map
that retains the order in which elements are inserted.
PipelineCompileQueue will then build the shaders in the order that they
were added by ContentContext.
)

https://skia.googlesource.com/skia.git/+log/7ef86a5b0eb9..f73c4510d12d

2026-07-31 michaelludwig@google.com [graphite] Track pipeline match and
cluster draws by pipeline in Layer

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/skia-flutter-autoroll
Please CC aaclarke@google.com,bwils@google.com,kjlubick@google.com on
the revert to ensure that a human
is aware of the problem.

To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry
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
…page draft)

Phase P0 of the Flutter Gradle Plugin migration to the AGP public API
surface (flutter#180137, flutter#166550): the contributor
migration record (replacement map, decision records, phase map,
revert-window table) and the draft of the user-facing breaking-change
page to be published to docs.flutter.dev before the newDsl flip reaches
beta.

Revert-safe: always.
@reidbaker
reidbaker self-requested a review as a code owner July 31, 2026 18:07
pull Bot pushed a commit to Little-Star888/flutter that referenced this pull request Aug 12, 2026
…on documentation (flutter#190842)

There are 2 files in this pr. One is a document the ai used to keep
track of work. More importantly it acts kind of like issues so it
references the items in future prs. The second is user facing website
documentation. I do not know if we will use it verbatim but for the set
of prs lets treat that md doc as human understandable documentation that
we must understand before landing the next pr.

Reviewers: When the pr is out of draft and your comments are fully
addressed please prioritize this pr over other work. The review bar is
higher, the number of reviews has more people and the work for the next
pr is already done.
 - @reidbaker 
---
Standard review context for this pr stack

This is PR is part of an 11 pr stack to migrate the "newdsl"
`gradle-api` specifically in agp 9.1.0.
The complete stack has pass pre submits, post submits and customer
tests.
https://flutter-dashboard.appspot.com/#/build?repo=flutter&branch=experimental/agp-gradle-api

All of the code was LLM authored. A mix of manual prompting, automatic
prompting, several models and adversarial review. The combined sessions
are enough that I cannot include relevant prompts like I have been doing
on other prs.

If you want to review the pr stack you can find it here. These prs will
be abandoned/closed as prs land into flutter/flutter.
1. reidbaker-agent#1 (branch:
agp-api-doc)
2. reidbaker-agent#2 (branch:
agp-internal-utils)
3. reidbaker-agent#3 (branch:
agp-buildmode-deps)
4. reidbaker-agent#4 (branch:
agp-plugin-buildtypes)
5. reidbaker-agent#5 (branch:
agp-ndk-fallback)
6. reidbaker-agent#6 (branch:
agp-assets-onvariants)
7. reidbaker-agent#7 (branch:
agp-apk-copy-versioncode)
8. reidbaker-agent#8 (branch:
agp-add-to-app)
9. reidbaker-agent#9 (branch:
agp-aar-script)
10. reidbaker-agent#10 (branch:
agp-newdsl-flip)
11. reidbaker-agent#11 (branch:
agp-gradle-api)

Follow up work is tracked in
flutter#190964

This work is urgent in the sense that we are worried that android will
publish agp 10 with no opt out but not so urgent that we are willing to
break flutter users because we didn't review or understand the code
because we were in a rush.

Breaking changes are expected as part of this work. There are patterns
the android team explicitly does not want apps to use and apis that have
no equivalent.

As part of the effort to ensure this work does not slip into ai slop,
prs from this stack will be reviewed by me (@reidbaker) before asking
for review. Then we will have 2 android expert reviewers also review the
every pr.

---
Agent authored pr description
This is PR 1 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack.

It adds the contributor-facing and website draft documentation for the
Flutter Gradle Plugin's migration to the Android Gradle Plugin public
Variant API, which unblocks building Flutter Android apps with AGP's
`newDsl=true` enabled.

Part of flutter#180137 and flutter#166550.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: reidbaker-agent <reidbaker@google.com>
@reidbaker reidbaker closed this Aug 14, 2026
okorohelijah pushed a commit to okorohelijah/flutter that referenced this pull request Aug 17, 2026
…90957)

This is PR 2 of 11 in the AGP 9.1.0 / public `gradle-api`/ newdls
migration stack.

This PR extracts some common utilities used in the Flutter Gradle Plugin
to internal functions, to be used in upcoming PRs in this stack. It also
introduces a typesafe CompileSdkVersion that handles comparisons between
api versions and preview versions which are strings.

First attempt was here flutter#190949
this pr includes my feedback from that first review. The first attempt
did not follow the pattern of having the agent account open the pr
because of rebase shenanigans that ended up touching freeze.yml.

---
Standard review context for this pr stack

This is PR is part of an 11 pr stack to migrate the "newdsl"
`gradle-api` specifically in agp 9.1.0.
The complete stack has pass pre submits, post submits and customer
tests.
https://flutter-dashboard.appspot.com/#/build?repo=flutter&branch=experimental/agp-gradle-api

All of the code was LLM authored. A mix of manual prompting, automatic
prompting, several models and adversarial review. The combined sessions
are enough that I cannot include relevant prompts like I have been doing
on other prs.

If you want to review the pr stack you can find it here. These prs will
be abandoned/closed as prs land into flutter/flutter.
1. reidbaker-agent#1 (branch:
agp-api-doc)
2. reidbaker-agent#2 (branch:
agp-internal-utils)
3. reidbaker-agent#3 (branch:
agp-buildmode-deps)
4. reidbaker-agent#4 (branch:
agp-plugin-buildtypes)
5. reidbaker-agent#5 (branch:
agp-ndk-fallback)
6. reidbaker-agent#6 (branch:
agp-assets-onvariants)
7. reidbaker-agent#7 (branch:
agp-apk-copy-versioncode)
8. reidbaker-agent#8 (branch:
agp-add-to-app)
9. reidbaker-agent#9 (branch:
agp-aar-script)
10. reidbaker-agent#10 (branch:
agp-newdsl-flip)
11. reidbaker-agent#11 (branch:
agp-gradle-api)

This work is urgent in the sense that we are worried that android will
publish agp 10 with no opt out but not so urgent that we are willing to
break flutter users because we didn't review or understand the code
because we were in a rush.

Breaking changes are expected as part of this work. There are patterns
the android team explicitly does not want apps to use and apis that have
no equivalent.

As part of the effort to ensure this work does not slip into ai slop,
prs from this stack will be reviewed by me (@reidbaker) before asking
for review. Then we will have 2 android expert reviewers also review the
every pr.

--- 
Agent authored description. 
This is PR 2 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack.

This PR extracts some common utilities used in the Flutter Gradle Plugin
to internal functions, to be used in upcoming PRs in this stack.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: reidbaker-agent <reidbaker@google.com>
Co-authored-by: Reid Baker <1063596+reidbaker@users.noreply.github.com>
pull Bot pushed a commit to TheRakeshPurohit/flutter that referenced this pull request Aug 24, 2026
…dependencies through the new DSL (flutter#191218)

This is PR 3 of 11 in the AGP 9.1.0 / public `gradle-api`/ newdsl
migration stack.

* It migrates many (but not all) usages of getLegacyAndroidExtension. 
* Introduces consistency in renaming of imports. 
* Adds a test to ensure we are not adding internal apis (thanks
@mboetger from pr1)
* builds the ability to run our gradle tests with multiple AGP versions
(see packages/flutter_tools/gradle/build.gradle.kts)

Between PR 3 and PR 8, an Add-to-app host app embedding a Flutter module
with a custom build type (for example "staging") gets release engine
artifacts. That means hot reload, debugger attach, and DevTools do not
operate in that build.
We can't move the work in PR 8 up but I would not want to cut a release
between this pr and 8 landing. If we keep reviewing one pr a day then
that is not a risk.

Apps impacted by this change can use matchingFallbacks to avoid this
problem (see code below).

In pr 8 we change when we look for "isDebuggable" to much later in the
gradle lifeycle when all the variants have been created which then lets
us use a new api to understand if the variant is intended to be
debuggable.

Kotlin 
```kotlin
// host app build.gradle.kts
android {
    buildTypes {
        create("staging") {
            isDebuggable = true
            applicationIdSuffix = ".staging"
            matchingFallbacks += "debug" /// This line. 
        }
    }
}
```
Groovy 
```groovy
// host app build.gradle
android {
    buildTypes {
        staging {
            debuggable true
            applicationIdSuffix ".staging"
            matchingFallbacks = ['debug'] /// This line. 
        }
    }
}
```

Depends on flutter#190957 (PR 2).
- @reidbaker 


---
Standard review context for this pr stack

This is PR is part of an 11 pr stack to migrate the "newdsl"
`gradle-api` specifically in agp 9.1.0.
The complete stack has passed presubmits, postsubmits, and customer
tests:
https://flutter-dashboard.appspot.com/#/build?repo=flutter&branch=experimental/agp-gradle-api

All of the code was LLM authored. A mix of manual prompting, automatic
prompting, several models and adversarial review. The combined sessions
are enough that I cannot include relevant prompts like I have been doing
on other prs.

If you want to review the pr stack you can find it here. These prs will
be abandoned/closed as prs land into flutter/flutter.
1. reidbaker-agent#1 (branch:
agp-api-doc)
2. reidbaker-agent#2 (branch:
agp-internal-utils)
3. reidbaker-agent#3 (branch:
agp-buildmode-deps)
4. reidbaker-agent#4 (branch:
agp-plugin-buildtypes)
5. reidbaker-agent#5 (branch:
agp-ndk-fallback)
6. reidbaker-agent#6 (branch:
agp-assets-onvariants)
7. reidbaker-agent#7 (branch:
agp-apk-copy-versioncode)
8. reidbaker-agent#8 (branch:
agp-add-to-app)
9. reidbaker-agent#9 (branch:
agp-aar-script)
10. reidbaker-agent#10 (branch:
agp-newdsl-flip)
11. reidbaker-agent#11 (branch:
agp-gradle-api)

This work is urgent in the sense that we are worried that android will
publish agp 10 with no opt out but not so urgent that we are willing to
break flutter users because we didn't review or understand the code
because we were in a rush.

Breaking changes are expected as part of this work. There are patterns
the android team explicitly does not want apps to use and apis that have
no equivalent.

As part of the effort to ensure this work does not slip into ai slop,
prs from this stack will be reviewed by me (@reidbaker) before asking
for review. Then we will have 2 android expert reviewers also review
every pr.

--- 
Agent authored description. 
This is PR 3 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack (flutter#180137, flutter#166550).

### Key Changes
- **DSL Build Mode Overloads**: Adds `buildModeFor` overloads accepting
`ApplicationBuildType`, `DynamicFeatureBuildType`, and
`LibraryBuildType` DSL types alongside the `(buildTypeName,
isDebuggable)` core overload.
- **Robust CompileSdkVersion Domain Model**: Extracts
`CompileSdkVersion` with constructor invariant validation (`init {
require(...) }`) enforcing mutual exclusivity between `apiLevel` and
`previewCodename`.
- **Namespaced Multi-AGP Build Property**: Namespaces the AGP version
property in `packages/flutter_tools/gradle/build.gradle.kts` as
`flutter.internal.agpVersion` (defaulting to `8.11.1`) to prevent user
app properties from leaking into the included build during app
compilation.
- **Standardized Type Aliasing**: Applies non-temporal type aliasing
(`import com.android.build.api.dsl.BuildType as DslBuildType`) across
`FlutterPlugin.kt` and `PluginHandler.kt`.
- **Public DSL Extension Access**: Updates `addFlutterDependencies` and
`PluginHandler` to iterate `AgpCommonExtensionWrapper.buildTypes`.
- **Build & Bytecode Validation**: Adds the
`:validateNoCommonExtensionInBytecode` task in `build.gradle.kts` to
prevent compiled main classes from referencing binary-incompatible
`CommonExtension`, and adds `BytecodeValidatorTest.kt` verifying the
binary pattern-matching and class scanning logic.
- **Comprehensive Unit Tests**: Adds full 4-way dispatch test coverage
in `AgpCommonExtensionWrapperTest`, dependency wiring tests in
`FlutterPluginTest`, and decomposes `PluginHandlerTest` mock fixtures
into focused helpers with positive assertions.

### Add-to-App & DSL Scope Context
`LibraryBuildType` does not expose `isDebuggable` at DSL scope. In PR 3,
custom build types on library projects (e.g. host app 'staging') fall
back to `"release"` at DSL scope. In PR 8 ("Unify add-to-app module
wiring on the variant API"), module wiring will be unified on
`Component.debuggable` at variant scope.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: reidbaker-agent <reidbaker@google.com>
Co-authored-by: Reid Baker <1063596+reidbaker@users.noreply.github.com>
NikhilKukreja26 pushed a commit to NikhilKukreja26/flutter that referenced this pull request Aug 28, 2026
…nitWith on public DSL (flutter#191606)

This is PR 4 of 11 in the AGP 9.1.0 / public `gradle-api` / newdsl
migration stack.

There are no breaking changes expected in this pr. Only internal logic
is impacted.

I will be honest I also found the tests hard to review. I had the agent
pull out shared mocking logic but I am not sure that actually made
review easier.

Depends on flutter#191218 (PR 3).
- @reidbaker

---
Standard review context for this pr stack

This is PR is part of an 11 pr stack to migrate the "newdsl"
`gradle-api` specifically in agp 9.1.0.

All of the code was LLM authored. A mix of manual prompting, automatic
prompting, several models and adversarial review. The combined sessions
are enough that I cannot include relevant prompts like I have been doing
on other prs.

If you want to review the pr stack you can find it here. These prs will
be abandoned/closed as prs land into flutter/flutter.
1. reidbaker-agent#1 (branch:
agp-api-doc)
2. reidbaker-agent#2 (branch:
agp-internal-utils)
3. reidbaker-agent#3 (branch:
agp-buildmode-deps)
4. reidbaker-agent#4 (branch:
agp-plugin-buildtypes)
5. reidbaker-agent#5 (branch:
agp-ndk-fallback)
6. reidbaker-agent#6 (branch:
agp-assets-onvariants)
7. reidbaker-agent#7 (branch:
agp-apk-copy-versioncode)
8. reidbaker-agent#8 (branch:
agp-add-to-app)
9. reidbaker-agent#9 (branch:
agp-aar-script)
10. reidbaker-agent#10 (branch:
agp-newdsl-flip)
11. reidbaker-agent#11 (branch:
agp-gradle-api)

This work is urgent in the sense that we are worried that android will
publish agp 10 with no opt out but not so urgent that we are willing to
break flutter users because we didn't review or understand the code
because we were in a rush.

Breaking changes are expected as part of this work. There are patterns
the android team explicitly does not want apps to use and apis that have
no equivalent.

As part of the effort to ensure this work does not slip into ai slop,
prs from this stack will be reviewed by me (@reidbaker) before asking
for review. Then we will have 2 android expert reviewers also review
every pr.

---
Agent authored description.
This is PR 4 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack (flutter#180137, flutter#166550).

### Key Changes
- **Public DSL `initWith` Copy**: Replaces the legacy
`getLegacyAndroidExtension` build-type copy in `PluginHandler` with
`initWith` on the public DSL (`AgpCommonExtensionWrapper.buildTypes`).
Missing build types on the plugin project are created with
`initWith(appBuildType)`, and `isDebuggable` is copied when both sides
are `ApplicationBuildType`.
- **Zero AGP Internals in Production Sources**: Removes the last
remaining `com.android.build.gradle.internal` imports from production
code (`src/main`).
- **Internal AGP Import Guard**: Adds `InternalAgpApiImportTest` to
continuously enforce that production sources do not introduce
`com.android.build.gradle.internal.*` imports.
- **Decomposed & Robust Unit Tests**: Replaces legacy mock-only tests in
`PluginHandlerTest` with tests that execute `configurePlugins` and
verify `initWith` copying for both library and application plugin
projects, mapping custom debuggable build types to debug engine
artifacts, and verifying that pre-existing plugin build types are
skipped.
- **Migration Documentation Update**: Adds details for the P3 pre-spike
and `finalizeDsl` fallback in
`Migrating-Flutter-Gradle-Plugin-to-AGP-public-API.md`.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
bkonyi pushed a commit to bkonyi/flutter that referenced this pull request Sep 4, 2026
… NDK fallback to public DSL (flutter#192116)

This is PR 5 of 11 in the AGP 9.1.0 / public `gradle-api` / newdsl
migration stack.

Add externalNativeBuild to the shared type. Extracted some shared
mocking logic to a utility.
No external visible changes expected. 
Also improved the README.md so that the test file for multiple agp
versions was a markdown link.

- @reidbaker

---
Standard review context for this pr stack

This is PR is part of an 11 pr stack to migrate the "newdsl"
`gradle-api` specifically in agp 9.1.0.

All of the code was LLM authored. A mix of manual prompting, automatic
prompting, several models and adversarial review. The combined sessions
are enough that I cannot include relevant prompts like I have been doing
on other prs.

If you want to review the pr stack you can find it here. These prs will
be abandoned/closed as prs land into flutter/flutter.
1. reidbaker-agent#1 (branch:
agp-api-doc)
2. reidbaker-agent#2 (branch:
agp-internal-utils)
3. reidbaker-agent#3 (branch:
agp-buildmode-deps)
4. reidbaker-agent#4 (branch:
agp-plugin-buildtypes)
5. reidbaker-agent#5 (branch:
agp-ndk-fallback)
6. reidbaker-agent#6 (branch:
agp-assets-onvariants)
7. reidbaker-agent#7 (branch:
agp-apk-copy-versioncode)
8. reidbaker-agent#8 (branch:
agp-add-to-app)
9. reidbaker-agent#9 (branch:
agp-aar-script)
10. reidbaker-agent#10 (branch:
agp-newdsl-flip)
11. reidbaker-agent#11 (branch:
agp-gradle-api)

This work is urgent in the sense that we are worried that android will
publish agp 10 with no opt out but not so urgent that we are willing to
break flutter users because we didn't review or understand the code
because we were in a rush.

Breaking changes are expected as part of this work. There are patterns
the android team explicitly does not want apps to use and apis that have
no equivalent.

As part of the effort to ensure this work does not slip into ai slop,
prs from this stack will be reviewed by me (@reidbaker) before asking
for review. Then we will have 2 android expert reviewers also review
every pr.

---
Agent authored description.
This is PR 5 of 11 in the AGP 9.1.0 / public `gradle-api` migration
stack (flutter#180137, flutter#166550).

### Key Changes
- **Public DSL Wrapper `externalNativeBuild`**: Exposes `val
externalNativeBuild: ExternalNativeBuild` in
`AgpCommonExtensionWrapper.kt` dispatching across
`ApplicationExtension`, `LibraryExtension`, `DynamicFeatureExtension`,
and `TestExtension` without referencing `CommonExtension` (bypassing AGP
binary incompatibility).
- **Zero Legacy `BaseExtension` in Production Sources**: Deletes
`getLegacyAndroidExtension(project: Project): BaseExtension` and removes
the `com.android.build.gradle.BaseExtension` import from
`FlutterPluginUtils.kt`.
- **Public DSL NDK Fallback Configuration**: Migrates `forceNdkDownload`
and `configureSyntheticExternalNativeBuildFallback` in
`FlutterPluginUtils.kt` to `getAndroidExtension(gradleProject)` using
`externalNativeBuild.cmake` / `externalNativeBuild.ndkBuild`. Sets
`cmake.path = File(...)`, `cmake.buildStagingDirectory = ...`, and
`buildType.externalNativeBuild.cmake.arguments += ...` through the
public DSL while preserving the upstream PR flutter#187201 `ndkBuild.path`
check.
- **Unit Test Public DSL Mocking & Cleanup**: Migrates unit tests in
`FlutterPluginUtilsTest.kt` to mock public DSL types
(`ApplicationExtension`, `Cmake`, `NdkBuild`), asserts CMake arguments
by list content, deletes obsolete tests asserting
`ApplicationExtension`-vs-`BaseExtension` `ndkVersion` preference, and
removes unused `import io.mockk.called` as well as all legacy
`com.android.build.gradle.internal.*` imports.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
reidbaker pushed a commit that referenced this pull request Sep 17, 2026
…#192650)

Fixes flutter#192227

**Problem**

`AppDomain.launch` sends the `app.start` event, which carries the app
ID, before `ResidentRunner.run()` has compiled and called
`generator.accept()`. A client that acts on that ID immediately can land
an `app.restart` in the gap, producing a `recompile` against a compiler
with no accepted baseline. `frontend_server` then crashes on
`lastKnownGoodResult!`, and the app fails to start.

**Fix**

`AppDomain.restart` now waits on a new `AppInstance.started` before
entering the debounce queue, so the compiler is never asked to recompile
before it has a baseline.

**Demo**

No URLs: the bug is in the `flutter run --machine` daemon protocol, not
in rendered output, so a deployed build has no daemon to race.

Verified locally with a harness that sends `app.restart` during the
initial compile, which is the window this closes. Before, it reproduces
the exact trace from the issue and the app
dies:

    Null check operator used on a null value
#0 FrontendCompiler.writeJavaScriptBundle (frontend_server.dart:1100)
#1 FrontendCompiler.recompileDelta (frontend_server.dart:1312)
#2 listenAndCompile.<anonymous closure> (frontend_server.dart:1806)
    App failed to start

After, the restart is held until `app.started` and returns `code: 0`.
reidbaker pushed a commit that referenced this pull request Sep 29, 2026
Fixes flutter#110488.

### Background: The `testWidgets` Lifecycle
Understanding this change requires distinguishing between two layers of
`Future`s and two distinct verification steps in `testWidgets`:

#### 1. Two Layers of `Future`s
* **`testBody()` Future**: The closure containing the user's test logic.
* **`runTest()` Future**: The overall async harness returned by
`binding.runTest()`. It manages the test zone, unmounts the widget tree,
and resolves only after `testBody()` and test-specific verifications
finish.

#### 2. Two Distinct Verification Phases
* **Test-specific verifications (`invariantTester`)**: Passed as a
callback to `runTest` and executed synchronously inside `_runTestBody`
immediately after the `testBody()` Future completes and the widget tree
is unmounted. In `testWidgets`, this runs
`tester._endOfTestVerifications` to verify that tickers and semantics
handles were disposed.
* **Framework-level invariant checks**: Verifies global framework state,
including ensuring foundation/rendering/widgets debug flags were reset
and no non-periodic timers or animations remain.

#### 3. The Teardown Lifecycle & Root Cause of flutter#110488
When `testWidgets` runs:
1. `testWidgets` registers `test_package.addTearDown(binding.postTest)`
with `package:test`.
2. `testWidgets` calls and returns `binding.runTest(...)`.
3. Inside `testBody()`, users may register cleanups using `addTearDown`
(for example, `addTearDown(() => debugDefaultTargetPlatformOverride =
null)`).
4. `package:test` executes teardowns in **LIFO (reverse registration)
order** only *after* the Future returned by `runTest` completes.

Previously, framework-level invariant checks ran at the end of
`_runTestBody` *before* the `runTest` Future completed. As a result,
they ran before `package:test` executed any user-registered
`addTearDown` callbacks, causing tests that clean up debug flags via
`addTearDown` to fail invariant verification (flutter#110488).

The following diagram shows the code flow after this PR:
```
testWidgets(description, (tester) async { ... })
 │
 ├── 1. Registration Phase
 │    └── test_package.addTearDown(binding.postTest)     [Teardown Stack: #1]
 │
 ├── 2. Test Execution Phase: binding.runTest(...)
 │    │
 │    │   [ Future 1: testBody() ]
 │    ├──► Run testBody(tester)
 │    │     └── User calls addTearDown(...)              [Teardown Stack: #2]
 │    │
 │    │   [ Post-testBody cleanup (inside runTest) ]
 │    ├──► Unmount widget tree (runApp)
 │    ├──► Verification 1: invariantTester()             (tickers, semantics)
 │    └──► Set _shouldVerifyInvariants = true
 │
 │    [ Future 2: runTest() completes ]
 │
 └── 3. Teardown Phase: package:test executes in LIFO order
      │
      ├──► [Step 1] User Teardowns (Stack #2)
      │     └── e.g., debugDefaultTargetPlatformOverride = null
      │
      └──► [Step 2] binding.postTest() (Stack #1)
            ├── Verification 2: Framework Invariants     (debug vars, timers)
            ├── Reset Binding State                      (_currentFakeAsync, etc.)
            └── reportTestException(...)                 (if Verification 2 failed)
```
### Changes & Design Rationale
#### 1. Defer Framework Invariant Checks to `postTest`

Framework invariant checks (`_verifyInvariants()`,
`_verifyAutoUpdateGoldensUnset`, etc.) are moved from `_runTestBody`
into `TestWidgetsFlutterBinding.postTest`.
Because `testWidgets` registers `binding.postTest` before running the
test body, `package:test`'s LIFO teardown ordering guarantees that all
user-registered `addTearDown` callbacks execute before
`binding.postTest`.

#### 2. Clarifying the `postTest` Error Contract

Previously, `postTest` only performed state cleanup and did not check
invariants. Moving invariant checks into `postTest` introduced the
question of how invariant failures should be propagated: allowing
`postTest` to throw, or absorbing errors and reporting them via
`reportTestException`.

We explicitly define the contract of `postTest` to **not throw
exceptions**, reporting any invariant failures via
`reportTestException`:

* **Rationale & Trade-offs**:
* *Alternative considered (throwing)*: If `super.postTest()` threw on an
invariant failure, `package:test` would still capture the failure.
However, subclasses (`AutomatedTestWidgetsFlutterBinding`,
`LiveTestWidgetsFlutterBinding`, or custom bindings) override `postTest`
to reset their own state (e.g. nulling `_currentFakeAsync` / `_clock`,
or setting `_inTest = false`). Allowing `super.postTest()` to throw
would require every subclass to defensively wrap `super.postTest()` in
`try ... finally`. If any subclass omitted this, an invariant failure
would leave the binding in a dirty state and trigger cascading `!inTest`
failures in subsequent tests.
* *Chosen approach (non-throwing)*: Absorbing errors in `postTest` and
forwarding them to `reportTestException` guarantees that all cleanup in
base and subclass implementations executes sequentially without
defensive `try ... finally` boilerplate, while still cleanly failing the
test.

**Why this does not break existing behavior:**
In the previous implementation, when invariant assertions failed inside
`_runTestBody`, they were caught by `_testZone.handleUncaughtError` and
forwarded to `reportTestException` (which delegates to
`package:test.registerException`). They never escaped `runTest` as
unhandled thrown exceptions. Catching invariant failures in `postTest`
and routing them to `reportTestException` preserves this exact error
reporting pipeline, diagnostic output, and failure semantics without
disrupting teardown execution.

#### 3. Preserving Existing Behavior on Failed Tests
(`_shouldVerifyInvariants`)

Historically, `_runTestBody` only verified invariants if the test body
did not fail:

```dart
if (_pendingExceptionDetails == null) {
  // We only try to clean up and verify invariants if we didn't already
  // fail. If we got an exception already, then we instead leave everything
  // alone so that we don't cause more spurious errors.
  ...
  _verifyInvariants();
}
```

When invariant checks are moved to `postTest`,
`_pendingExceptionDetails` is no longer available because it has already
been reported and cleared by `testCompletionHandler` when `runTest`
completed.

To preserve this exact existing behavior across the lifecycle boundary,
`_shouldVerifyInvariants` is introduced. It is set to `true` at the end
of `_runTestBody` only when `_pendingExceptionDetails == null`. If a
test fails in its body, `_shouldVerifyInvariants` remains `false`, and
`postTest` skips invariant checks—ensuring no behavior change and
preventing spurious errors (e.g. active animations on an unmounted tree)
from masking the real failure.

#### 4. Documentation Updates
Updated the doc comments on:
* `TestWidgetsFlutterBinding.postTest`: Documents the non-throwing
contract, the `@mustCallSuper` requirement, and error reporting via
`reportTestException`.
* `TestWidgetsFlutterBinding.runTest`: Clarifies the distinction between
`invariantTester` (which runs before `runTest` completes) and framework
invariant checks (which run in `postTest` after `runTest` and user
teardowns complete).

### Tests
- Added unit tests in
`packages/flutter_test/test/bindings_invariants_test.dart` verifying
that foundation variables (`debugDefaultTargetPlatformOverride`,
`debugDoublePrecision`, `debugBrightnessOverride`),
`autoUpdateGoldenFiles`, `ErrorWidget.builder`, and
`shouldPropagateDevicePointerEvents` can all be reset using
`addTearDown`.
- Added test cases verifying invariant failures in `postTest` and
ensuring invariant checks are skipped when the test body throws.

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
reidbaker pushed a commit that referenced this pull request Sep 29, 2026
)

Reverts: [Allow resetting test invariants in
`addTearDown`](flutter#192082)

Initiated by: @b-luk

Reason for reverting: Breaks tree with tool_integration_tests failures.
Example:
https://ci.chromium.org/ui/p/flutter/builders/prod/Mac%20tool_integration_tests_2/1329/overview

Original PR Author: @dkwingsmt

Reviewed By: @justinmc

The original PR description is provided below:

Fixes flutter#110488.

### Background: The `testWidgets` Lifecycle
Understanding this change requires distinguishing between two layers of
`Future`s and two distinct verification steps in `testWidgets`:

#### 1. Two Layers of `Future`s
* **`testBody()` Future**: The closure containing the user's test logic.
* **`runTest()` Future**: The overall async harness returned by
`binding.runTest()`. It manages the test zone, unmounts the widget tree,
and resolves only after `testBody()` and test-specific verifications
finish.

#### 2. Two Distinct Verification Phases
* **Test-specific verifications (`invariantTester`)**: Passed as a
callback to `runTest` and executed synchronously inside `_runTestBody`
immediately after the `testBody()` Future completes and the widget tree
is unmounted. In `testWidgets`, this runs
`tester._endOfTestVerifications` to verify that tickers and semantics
handles were disposed.
* **Framework-level invariant checks**: Verifies global framework state,
including ensuring foundation/rendering/widgets debug flags were reset
and no non-periodic timers or animations remain.

#### 3. The Teardown Lifecycle & Root Cause of flutter#110488
When `testWidgets` runs:
1. `testWidgets` registers `test_package.addTearDown(binding.postTest)`
with `package:test`.
2. `testWidgets` calls and returns `binding.runTest(...)`.
3. Inside `testBody()`, users may register cleanups using `addTearDown`
(for example, `addTearDown(() => debugDefaultTargetPlatformOverride =
null)`).
4. `package:test` executes teardowns in **LIFO (reverse registration)
order** only *after* the Future returned by `runTest` completes.

Previously, framework-level invariant checks ran at the end of
`_runTestBody` *before* the `runTest` Future completed. As a result,
they ran before `package:test` executed any user-registered
`addTearDown` callbacks, causing tests that clean up debug flags via
`addTearDown` to fail invariant verification (flutter#110488).

The following diagram shows the code flow after this PR:
```
testWidgets(description, (tester) async { ... })
 │
 ├── 1. Registration Phase
 │    └── test_package.addTearDown(binding.postTest)     [Teardown Stack: #1]
 │
 ├── 2. Test Execution Phase: binding.runTest(...)
 │    │
 │    │   [ Future 1: testBody() ]
 │    ├──► Run testBody(tester)
 │    │     └── User calls addTearDown(...)              [Teardown Stack: #2]
 │    │
 │    │   [ Post-testBody cleanup (inside runTest) ]
 │    ├──► Unmount widget tree (runApp)
 │    ├──► Verification 1: invariantTester()             (tickers, semantics)
 │    └──► Set _shouldVerifyInvariants = true
 │
 │    [ Future 2: runTest() completes ]
 │
 └── 3. Teardown Phase: package:test executes in LIFO order
      │
      ├──► [Step 1] User Teardowns (Stack #2)
      │     └── e.g., debugDefaultTargetPlatformOverride = null
      │
      └──► [Step 2] binding.postTest() (Stack #1)
            ├── Verification 2: Framework Invariants     (debug vars, timers)
            ├── Reset Binding State                      (_currentFakeAsync, etc.)
            └── reportTestException(...)                 (if Verification 2 failed)
```
### Changes & Design Rationale
#### 1. Defer Framework Invariant Checks to `postTest`

Framework invariant checks (`_verifyInvariants()`,
`_verifyAutoUpdateGoldensUnset`, etc.) are moved from `_runTestBody`
into `TestWidgetsFlutterBinding.postTest`.
Because `testWidgets` registers `binding.postTest` before running the
test body, `package:test`'s LIFO teardown ordering guarantees that all
user-registered `addTearDown` callbacks execute before
`binding.postTest`.

#### 2. Clarifying the `postTest` Error Contract

Previously, `postTest` only performed state cleanup and did not check
invariants. Moving invariant checks into `postTest` introduced the
question of how invariant failures should be propagated: allowing
`postTest` to throw, or absorbing errors and reporting them via
`reportTestException`.

We explicitly define the contract of `postTest` to **not throw
exceptions**, reporting any invariant failures via
`reportTestException`:

* **Rationale & Trade-offs**:
* *Alternative considered (throwing)*: If `super.postTest()` threw on an
invariant failure, `package:test` would still capture the failure.
However, subclasses (`AutomatedTestWidgetsFlutterBinding`,
`LiveTestWidgetsFlutterBinding`, or custom bindings) override `postTest`
to reset their own state (e.g. nulling `_currentFakeAsync` / `_clock`,
or setting `_inTest = false`). Allowing `super.postTest()` to throw
would require every subclass to defensively wrap `super.postTest()` in
`try ... finally`. If any subclass omitted this, an invariant failure
would leave the binding in a dirty state and trigger cascading `!inTest`
failures in subsequent tests.
* *Chosen approach (non-throwing)*: Absorbing errors in `postTest` and
forwarding them to `reportTestException` guarantees that all cleanup in
base and subclass implementations executes sequentially without
defensive `try ... finally` boilerplate, while still cleanly failing the
test.

**Why this does not break existing behavior:**
In the previous implementation, when invariant assertions failed inside
`_runTestBody`, they were caught by `_testZone.handleUncaughtError` and
forwarded to `reportTestException` (which delegates to
`package:test.registerException`). They never escaped `runTest` as
unhandled thrown exceptions. Catching invariant failures in `postTest`
and routing them to `reportTestException` preserves this exact error
reporting pipeline, diagnostic output, and failure semantics without
disrupting teardown execution.

#### 3. Preserving Existing Behavior on Failed Tests
(`_shouldVerifyInvariants`)

Historically, `_runTestBody` only verified invariants if the test body
did not fail:

```dart
if (_pendingExceptionDetails == null) {
  // We only try to clean up and verify invariants if we didn't already
  // fail. If we got an exception already, then we instead leave everything
  // alone so that we don't cause more spurious errors.
  ...
  _verifyInvariants();
}
```

When invariant checks are moved to `postTest`,
`_pendingExceptionDetails` is no longer available because it has already
been reported and cleared by `testCompletionHandler` when `runTest`
completed.

To preserve this exact existing behavior across the lifecycle boundary,
`_shouldVerifyInvariants` is introduced. It is set to `true` at the end
of `_runTestBody` only when `_pendingExceptionDetails == null`. If a
test fails in its body, `_shouldVerifyInvariants` remains `false`, and
`postTest` skips invariant checks—ensuring no behavior change and
preventing spurious errors (e.g. active animations on an unmounted tree)
from masking the real failure.

#### 4. Documentation Updates
Updated the doc comments on:
* `TestWidgetsFlutterBinding.postTest`: Documents the non-throwing
contract, the `@mustCallSuper` requirement, and error reporting via
`reportTestException`.
* `TestWidgetsFlutterBinding.runTest`: Clarifies the distinction between
`invariantTester` (which runs before `runTest` completes) and framework
invariant checks (which run in `postTest` after `runTest` and user
teardowns complete).

### Tests
- Added unit tests in
`packages/flutter_test/test/bindings_invariants_test.dart` verifying
that foundation variables (`debugDefaultTargetPlatformOverride`,
`debugDoublePrecision`, `debugBrightnessOverride`),
`autoUpdateGoldenFiles`, `ErrorWidget.builder`, and
`shouldPropagateDevicePointerEvents` can all be reset using
`addTearDown`.
- Added test cases verifying invariant failures in `postTest` and
ensuring invariant checks are skipped when the test body throws.

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
reidbaker pushed a commit that referenced this pull request Oct 2, 2026
Issue: flutter#193579.

This is a fix for the following error:
```
Processing /Volumes/Work/s/w/ir/x/w/flutter/bin/cache/pkg/tests/registry/flutter_cocoon.test...
Unhandled exception:
ProcessException: No such file or directory
  Command: ./test_utilities/bin/flutter_test_runner.sh dashboard
#0      _ProcessImpl._start (dart:io-patch/process_patch.dart:411:33)
#1      Process.start (dart:io-patch/process_patch.dart:42:20)
#2      shell (file:///Volumes/Work/s/w/ir/x/w/flutter/dev/customer_testing/lib/runner.dart:236:29)
#3      runTests (file:///Volumes/Work/s/w/ir/x/w/flutter/dev/customer_testing/lib/runner.dart:172:31)
<asynchronous suspension>
#4      main (file:///Volumes/Work/s/w/ir/x/w/flutter/dev/customer_testing/run_tests.dart:15:8)
<asynchronous suspension>
```
reidbaker-agent pushed a commit that referenced this pull request Oct 22, 2026
…rror 206) (flutter#194867)

When a Flutter project, SDK, or subprocess command path on Windows
exceeds `MAX_PATH` (260 characters), Win32 process and file operations
fail with OS error code `206` (`ERROR_FILENAME_EXCED_RANGE`: `The
filename or extension is too long`). Previously,
`_handleWindowsException` in `error_handling_io.dart` did not recognize
error code `206`, causing `ErrorHandlingProcessManager` and
`ErrorHandlingFileSystem` to rethrow an unhandled
`ProcessPackageException` or `FileSystemException` and trigger a crash
report.

Add `kFilenameExcedRange = 206` to `_handleWindowsException` so
operations failing with error code `206` exit cleanly with a `ToolExit`
instructing the user to move the Flutter SDK and/or project to a shorter
path or enable long paths on Windows.

### Previous output
```text
Unhandled exception:
ProcessPackageException: ProcessException: The filename or extension is too long
  Command: C:\Users\User\AppData\Local\Temp\...
#0      LocalProcessManager.runSync (package:process/src/interface/local_process_manager.dart:118)
#1      ErrorHandlingProcessManager.runSync.<anonymous closure> (package:flutter_tools/src/base/error_handling_io.dart:1310)
#2      _runSync (package:flutter_tools/src/base/error_handling_io.dart:1118)
#3      ErrorHandlingProcessManager.runSync (package:flutter_tools/src/base/error_handling_io.dart:1308)
#4      _DefaultPub._preloadPubCache (package:flutter_tools/src/dart/pub.dart:645)
```

### Current output
```text
Flutter failed to run "C:\Users\User\AppData\Local\Temp\...". The filename or extension is too long.
ProcessException: The filename or extension is too long
  Command: C:\Users\User\AppData\Local\Temp\...
Please consider moving the Flutter SDK and/or project to a shorter path, or enabling long paths on Windows.
```

Fixes flutter#194570
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.