[CP-stable][reland] Fix regression in NDK version checking (#169289)

This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request)
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.

### Issue Link:
What is the link to the issue this cherry-pick is addressing?

There was no associated issue, but the problem is that https://github.com/flutter/flutter/pull/166727 broke Flutter Android builds on apps that use plugins with AGP versions less than 8.2.

### Changelog Description:
Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/blob/main/docs/releases/Hotfix-Documentation-Best-Practices.md) for examples

Fixes Flutter Android builds for apps which use plugins with old Android Gradle Plugin versions.

### Impact Description:
What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch)

The impact is a crash in the build process.

### Workaround:
Is there a workaround for this issue?

No

### Risk:
What is the risk level of this cherry-pick?

### Test Coverage:
Are you confident that your fix is well-tested by automated tests?

### Validation Steps:
What are the steps to validate that this fix works?

Build an app that uses AGP < 8.2.
This commit is contained in:
flutteractionsbot 2025-05-23 09:56:15 -07:00 committed by GitHub
parent 673806fbc1
commit 44b32ecbb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 6 deletions

View File

@ -1520,10 +1520,12 @@ targets:
test_timeout_secs: "2700"
runIf:
- packages/flutter_tools/templates/**
- packages/flutter_tools/gradle/**
- .ci.yaml
- engine/**
- DEPS
- dev/devicelab/bin/tasks/android_java11_dependency_smoke_tests.dart
- dev/devicelab/lib/framework/dependency_smoke_test_task_definition.dart
- name: Linux android_java17_dependency_smoke_tests
recipe: devicelab/devicelab_drone
@ -1542,10 +1544,12 @@ targets:
test_timeout_secs: "2700"
runIf:
- packages/flutter_tools/templates/**
- packages/flutter_tools/gradle/**
- .ci.yaml
- engine/**
- DEPS
- dev/devicelab/bin/tasks/android_java17_dependency_smoke_tests.dart
- dev/devicelab/lib/framework/dependency_smoke_test_task_definition.dart
- name: Linux tool_tests_commands
recipe: flutter/flutter_drone

View File

@ -40,11 +40,14 @@ List<VersionTuple> versionTuples = <VersionTuple>[
kotlinVersion: '1.7.10',
compileSdkVersion: '34',
),
// minSdk bump required due to a bug in the default version of r8 used by AGP
// 7.4.0. See http://issuetracker.google.com/issues/357553178.
VersionTuple(
agpVersion: '7.4.0',
gradleVersion: '7.5',
kotlinVersion: '1.8.10',
compileSdkVersion: '34',
minSdkVersion: '24',
),
];

View File

@ -61,6 +61,7 @@ distributionUrl=https\://services.gradle.org/distributions/gradle-GRADLE_REPLACE
const String gradleReplacementString = 'GRADLE_REPLACE_ME';
final RegExp flutterCompileSdkString = RegExp(r'flutter\.compileSdkVersion|flutter\.compileSdk');
final RegExp flutterMinSdkString = RegExp(r'flutter\.minSdkVersion|flutter\.minSdk');
/// A simple class containing a Kotlin, Gradle, and AGP version.
class VersionTuple {
@ -69,12 +70,14 @@ class VersionTuple {
required this.gradleVersion,
required this.kotlinVersion,
this.compileSdkVersion,
this.minSdkVersion,
});
String agpVersion;
String gradleVersion;
String kotlinVersion;
String? compileSdkVersion;
String? minSdkVersion;
@override
String toString() {
@ -108,10 +111,10 @@ Future<TaskResult> buildFlutterApkWithSpecifiedDependencyVersions({
final String appPath = '${innerTempDir.absolute.path}/dependency_checker_app';
final File appGradleBuild = getAndroidBuildFile(
localFileSystem.path.join(appPath, 'android', 'app'),
);
if (versions.compileSdkVersion != null) {
final File appGradleBuild = getAndroidBuildFile(
localFileSystem.path.join(appPath, 'android', 'app'),
);
final String appBuildContent = appGradleBuild.readAsStringSync().replaceFirst(
flutterCompileSdkString,
versions.compileSdkVersion!,
@ -119,6 +122,14 @@ Future<TaskResult> buildFlutterApkWithSpecifiedDependencyVersions({
appGradleBuild.writeAsStringSync(appBuildContent);
}
if (versions.minSdkVersion != null) {
final String appBuildContent = appGradleBuild.readAsStringSync().replaceFirst(
flutterMinSdkString,
versions.minSdkVersion!,
);
appGradleBuild.writeAsStringSync(appBuildContent);
}
// Modify gradle version to passed in version.
final File gradleWrapperProperties = localFileSystem.file(
localFileSystem.path.join(
@ -144,6 +155,13 @@ Future<TaskResult> buildFlutterApkWithSpecifiedDependencyVersions({
.replaceFirst(kgpReplacementString, versions.kotlinVersion);
await gradleSettingsFile.writeAsString(settingsContent, flush: true);
section('Add a dependency on a plugin');
await flutter(
'pub',
options: <String>['add', 'shared_preferences_android:2.4.7'], // Chosen randomly.
workingDirectory: appPath,
);
// Ensure that gradle files exists from templates.
section(
"Ensure 'flutter build apk' succeeds with Gradle ${versions.gradleVersion}, AGP ${versions.agpVersion}, and Kotlin ${versions.kotlinVersion}",

View File

@ -517,8 +517,16 @@ object FlutterPluginUtils {
getCompileSdkFromProject(project).toIntOrNull() ?: Int.MAX_VALUE
var maxPluginCompileSdkVersion = projectCompileSdkVersion
val projectNdkVersion =
getAndroidExtension(project).ndkVersion
// TODO(gmackall): This should be updated to reflect newer templates.
// The default for AGP 4.1.0 used in old templates.
val ndkVersionIfUnspecified = "21.1.6352462"
// TODO(gmackall): We can remove this elvis when our minimum AGP is >= 8.2.
// This value (ndkVersion) is nullable on AGP versions below that.
// See https://developer.android.com/reference/tools/gradle-api/8.1/com/android/build/api/dsl/CommonExtension#ndkVersion().
@Suppress("USELESS_ELVIS")
val projectNdkVersion: String =
getAndroidExtension(project).ndkVersion ?: ndkVersionIfUnspecified
var maxPluginNdkVersion = projectNdkVersion
var numProcessedPlugins = pluginList.size
val pluginsWithHigherSdkVersion = mutableListOf<PluginVersionPair>()
@ -543,8 +551,13 @@ object FlutterPluginUtils {
)
)
}
// TODO(gmackall): We can remove this elvis when our minimum AGP is >= 8.2.
// This value (ndkVersion) is nullable on AGP versions below that.
// See https://developer.android.com/reference/tools/gradle-api/8.1/com/android/build/api/dsl/CommonExtension#ndkVersion().
@Suppress("USELESS_ELVIS")
val pluginNdkVersion: String =
getAndroidExtension(pluginProject).ndkVersion
getAndroidExtension(pluginProject).ndkVersion ?: ndkVersionIfUnspecified
maxPluginNdkVersion =
VersionUtils.mostRecentSemanticVersion(
pluginNdkVersion,