Skip to content

[CP-beta]Fix Android license detection for cmdline-tools 23.0+ - #192132

Merged
auto-submit[bot] merged 1 commit into
flutter:flutter-3.48-candidate.0from
flutteractionsbot:cp-beta-9d0f24ee98b6063faa8499ebd8d20836bb8b9672
Sep 2, 2026
Merged

[CP-beta]Fix Android license detection for cmdline-tools 23.0+#192132
auto-submit[bot] merged 1 commit into
flutter:flutter-3.48-candidate.0from
flutteractionsbot:cp-beta-9d0f24ee98b6063faa8499ebd8d20836bb8b9672

Conversation

@flutteractionsbot

@flutteractionsbot flutteractionsbot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

This pull request is created by automatic cherry pick workflow
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.

Issue Link:

#191487

Impact Description:

Android SDK Command-line Tools 23.0 deprecated sdkmanager --licenses in favor of the new android CLI. When invoked, sdkmanager --licenses now only outputs a deprecation notice (Warning: The --licenses option is no longer needed.) rather than the parseable license summary flutter doctor previously depended on.

As a result, flutter doctor fails to parse license status and reports ✗ Android license status unknown. while prompting users to run flutter doctor --android-licenses, which fails to resolve the issue.

Changelog Description:

[flutter/191487] When using Android SDK Command-line Tools 23.0+ for Android, flutter doctor incorrectly reports "Android license status unknown".

Workaround:

  1. Downgrade Android SDK Command-line Tools to version 22.0 via the Android Studio SDK Manager or CLI.
  2. If licenses have already been accepted on disk in <Android-SDK>/licenses/, Android Gradle builds still succeed and the flutter doctor warning can be safely ignored (if the user knows to ignore).

Risk:

What is the risk level of this cherry-pick?

  • Low
  • Medium
  • High

Test Coverage:

Are you confident that your fix is well-tested by automated tests?

  • Yes
  • No

Validation Steps:

  1. Ensure Android SDK Command-line Tools 23.0 is installed (verify in $ANDROID_HOME/cmdline-tools/latest/source.properties that Pkg.Revision=23.0).
  2. Run flutter doctor -v.
  3. Verify that under Android toolchain, it reports • All Android licenses accepted. instead of ✗ Android license status unknown.
  4. (Optional negative check) Temporarily rename the $ANDROID_HOME/licenses directory, run flutter doctor -v, and verify it reports Android licenses not accepted. Restore the directory.

## Description

Fixes flutter#191487

Android SDK cmdline-tools 23.0 deprecated `sdkmanager --licenses` in
favor of the new `android` CLI. Running `sdkmanager --licenses` now only
prints a deprecation warning instead of the parseable license summary
Flutter previously relied on:

```
WARNING: The SDK Manager CLI tool (sdkmanager) is deprecated. Android CLI will be used instead.
The 'android' binary can also be found in the cmdline-tools directory, and 'android sdk' is the replacement for 'sdkmanager'.
To learn more about the Android CLI and how to use it, see the documentation (https://d.android.com/tools/agents/android-cli)
Warning: The --licenses option is no longer needed.
```

None of the existing regexes in `licensesAccepted` match this output, so
`flutter doctor` incorrectly reports `Android license status unknown`
even when licenses are actually accepted.

## Approach

I initially considered treating the new deprecation message as
`LicensesAccepted.all`, but testing against a real cmdline-tools 23.0
install showed this message prints identically whether or not the
licenses directory exists — so it can't be trusted as a signal of actual
license state. I verified this by temporarily renaming my
`<sdk>/licenses` directory and re-running `sdkmanager --licenses`; the
output was byte-for-byte identical either way.

I also checked the new `android` CLI's `--help` output (`sdk`, `sdk
install`, `info`) — there's no license-status subcommand or flag exposed
in this version, so there's no better structured signal to query
instead.

Since the SDK's actual license acceptance state is still tracked on disk
under `<sdk>/licenses/` (this is presumably what Gradle checks directly,
since Gradle builds still succeed after this cmdline-tools update), this
PR adds a narrow, additive fallback:

- When `sdkmanager`'s output matches the specific new-CLI deprecation
message (and only then — not for arbitrary unparseable/garbage output),
`licensesAccepted` checks the `licenses/` directory on disk directly
instead of trusting stdout.
- All existing regex-based parsing for older `sdkmanager` versions is
untouched.

## Known limitation

This fallback can only distinguish "some license files are present and
non-empty" (→ `all`) from "no license files at all" (→ `none`). It
cannot reproduce the previous `LicensesAccepted.some` state for the new
CLI, since that information is no longer exposed by the tool in any form
I could find. Happy to adjust the approach if maintainers have a
preference here.

## Tests

Added two regression tests reproducing the exact real-world output
captured from a Windows machine running cmdline-tools 23.0:
- `licensesAccepted falls back to the licenses directory when sdkmanager
output is unparseable (new Android CLI, licenses present)`
- `licensesAccepted falls back to none when sdkmanager output is
unparseable and no licenses are present (new Android CLI, licenses
missing)`

All existing tests in `android_workflow_test.dart` continue to pass
(35/35).

Also manually verified end-to-end: `flutter doctor -v` on the affected
machine now correctly reports `All Android licenses accepted.` instead
of `Android license status unknown.`

---------

Co-authored-by: Gray Mackall <34871572+gmackall@users.noreply.github.com>
@flutteractionsbot
flutteractionsbot requested a review from a team as a code owner September 1, 2026 21:10
@flutteractionsbot flutteractionsbot added the cp: review Cherry-picks in the review queue label Sep 1, 2026
@flutteractionsbot
flutteractionsbot requested review from jesswrd and removed request for a team September 1, 2026 21:10
@flutteractionsbot

Copy link
Copy Markdown
Contributor Author

@gmackall please fill out the PR description above, afterwards the release team will review this request.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Sep 1, 2026
@flutter-dashboard

Copy link
Copy Markdown

This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter.

Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a fallback license check from disk when the Android sdkmanager output is unparseable due to deprecation warnings from newer Android CLI tools, and adds corresponding unit tests. The review feedback suggests catching FileSystemException on individual files within the licenses directory to prevent a single file error from failing the entire validation process.

Comment on lines +519 to +521
final bool hasAcceptedLicense = licensesDir.listSync().whereType<File>().any(
(File file) => !file.basename.startsWith('.') && file.lengthSync() > 0,
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If any individual file in the licenses directory throws a FileSystemException during file.lengthSync() (for example, due to a broken symlink or permission issues on a specific file), the exception will propagate out of any and cause the entire method to return LicensesAccepted.unknown. This happens even if there are other valid, accepted license files in the directory.

To make this check more robust, we can catch FileSystemException individually for each file inside the any block.

Suggested change
final bool hasAcceptedLicense = licensesDir.listSync().whereType<File>().any(
(File file) => !file.basename.startsWith('.') && file.lengthSync() > 0,
);
final bool hasAcceptedLicense = licensesDir.listSync().whereType<File>().any(
(File file) {
if (file.basename.startsWith('.')) {
return false;
}
try {
return file.lengthSync() > 0;
} on FileSystemException {
return false;
}
},
);

@github-actions github-actions Bot added tool Affects the "flutter" command-line tool. See also t: labels. team-android Owned by Android platform team labels Sep 1, 2026
@justinmc

justinmc commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@jesswrd / @gmackall can you guys fill out the PR description and confirm this is a reasonable CP?

There was one failure that looked like a flake so I reran it. I'll try to get this beta hotfix going later today.

@gmackall

gmackall commented Sep 2, 2026

Copy link
Copy Markdown
Member

@jesswrd / @gmackall can you guys fill out the PR description and confirm this is a reasonable CP?

There was one failure that looked like a flake so I reran it. I'll try to get this beta hotfix going later today.

Filled out, sorry for missing this when I added the label initially!

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@justinmc justinmc added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 2, 2026
@auto-submit
auto-submit Bot merged commit e3005e3 into flutter:flutter-3.48-candidate.0 Sep 2, 2026
12 checks passed
@flutteractionsbot
flutteractionsbot deleted the cp-beta-9d0f24ee98b6063faa8499ebd8d20836bb8b9672 branch September 2, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD cp: review Cherry-picks in the review queue team-android Owned by Android platform team tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants