Skip to content

Commit aa2afa5

Browse files
committed
fix(android): only skip when the configured ndk is installed
1 parent c1747a4 commit aa2afa5

2 files changed

Lines changed: 142 additions & 22 deletions

File tree

packages/flutter_tools/lib/src/android/gradle.dart

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ class AndroidGradleBuilder implements AndroidBuilder {
175175
_analytics = analytics,
176176
_gradleUtils = gradleUtils,
177177
_androidStudio = androidStudio,
178-
_platform = platform,
179178
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform),
180179
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
181180

@@ -188,7 +187,6 @@ class AndroidGradleBuilder implements AndroidBuilder {
188187
final GradleUtils _gradleUtils;
189188
final FileSystemUtils _fileSystemUtils;
190189
final AndroidStudio? _androidStudio;
191-
final Platform _platform;
192190

193191
/// Builds the AAR and POM files for the current Flutter module or plugin.
194192
@override
@@ -579,7 +577,11 @@ class AndroidGradleBuilder implements AndroidBuilder {
579577
gradleExecutablePath: gradleExecutablePath,
580578
buildInfo: buildInfo,
581579
)
582-
: _getExistingAndroidNdkSkipValue();
580+
: await _getInstalledConfiguredAndroidNdkVersion(
581+
project: project,
582+
gradleExecutablePath: gradleExecutablePath,
583+
buildInfo: buildInfo,
584+
);
583585
if (preprovisionedNdkVersion != null) {
584586
options.add('-P$_kPreprovisionedNdkVersionProperty=$preprovisionedNdkVersion');
585587
}
@@ -1045,21 +1047,26 @@ class AndroidGradleBuilder implements AndroidBuilder {
10451047
return result;
10461048
}
10471049

1048-
String? _getExistingAndroidNdkSkipValue() {
1050+
Future<String?> _getInstalledConfiguredAndroidNdkVersion({
1051+
required FlutterProject project,
1052+
required String gradleExecutablePath,
1053+
required BuildInfo buildInfo,
1054+
}) async {
10491055
final AndroidSdk? androidSdk = globals.androidSdk;
10501056
if (androidSdk == null || !androidSdk.directory.existsSync()) {
10511057
return null;
10521058
}
10531059

1054-
for (final Directory ndkDirectory in androidSdk.getNdkDirectoriesInResolutionOrder(
1055-
platform: _platform,
1056-
)) {
1057-
if (_isExistingAndroidNdkDirectory(ndkDirectory)) {
1058-
return ndkDirectory.basename;
1059-
}
1060+
final String? requiredNdkVersion = await _getNdkVersion(
1061+
project: project,
1062+
gradleExecutablePath: gradleExecutablePath,
1063+
buildInfo: buildInfo,
1064+
);
1065+
if (requiredNdkVersion == null) {
1066+
return null;
10601067
}
10611068

1062-
return null;
1069+
return androidSdk.hasNdkVersion(requiredNdkVersion) ? requiredNdkVersion : null;
10631070
}
10641071

10651072
@override
@@ -1524,7 +1531,3 @@ bool _shouldPreprovisionAndroidNdk(BuildInfo buildInfo) {
15241531
final String? flavor = buildInfo.flavor;
15251532
return flavor != null && flavor.isNotEmpty;
15261533
}
1527-
1528-
bool _isExistingAndroidNdkDirectory(Directory directory) {
1529-
return directory.childFile('source.properties').existsSync();
1530-
}

packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ void main() {
418418
);
419419

420420
testUsingContext(
421-
'build apk uses existing ndk for unflavored builds without querying printNdkVersion',
421+
'build apk uses the configured installed ndk for unflavored builds',
422422
() async {
423423
final builder = AndroidGradleBuilder(
424424
java: FakeJava(),
@@ -428,11 +428,15 @@ void main() {
428428
artifacts: Artifacts.test(),
429429
analytics: fakeAnalytics,
430430
gradleUtils: FakeGradleUtils(),
431-
platform: FakePlatform(
432-
environment: <String, String>{kAndroidNdkPath: ndkPath('28.2.13676358')},
433-
),
431+
platform: FakePlatform(),
434432
androidStudio: FakeAndroidStudio(),
435433
);
434+
processManager.addCommand(
435+
const FakeCommand(
436+
command: <String>['gradlew', '-q', 'printNdkVersion'],
437+
stdout: 'NdkVersion: 28.2.13676358\n',
438+
),
439+
);
436440
processManager.addCommand(
437441
const FakeCommand(
438442
command: <String>[
@@ -504,13 +508,11 @@ void main() {
504508
);
505509
},
506510
AndroidStudio: () => FakeAndroidStudio(),
507-
Platform: () =>
508-
FakePlatform(environment: <String, String>{kAndroidNdkPath: ndkPath('28.2.13676358')}),
509511
},
510512
);
511513

512514
testUsingContext(
513-
'build apk uses the latest existing ndk version for unflavored builds without querying printNdkVersion',
515+
'build apk uses the configured installed ndk version for unflavored builds',
514516
() async {
515517
final builder = AndroidGradleBuilder(
516518
java: FakeJava(),
@@ -523,6 +525,12 @@ void main() {
523525
platform: FakePlatform(),
524526
androidStudio: FakeAndroidStudio(),
525527
);
528+
processManager.addCommand(
529+
const FakeCommand(
530+
command: <String>['gradlew', '-q', 'printNdkVersion'],
531+
stdout: 'NdkVersion: 29.0.13846066\n',
532+
),
533+
);
526534
processManager.addCommand(
527535
const FakeCommand(
528536
command: <String>[
@@ -601,6 +609,103 @@ void main() {
601609
},
602610
);
603611

612+
testUsingContext(
613+
'build apk does not skip forced ndk download for unflavored builds when the configured ndk is missing',
614+
() async {
615+
final builder = AndroidGradleBuilder(
616+
java: FakeJava(),
617+
logger: logger,
618+
processManager: processManager,
619+
fileSystem: fileSystem,
620+
artifacts: Artifacts.test(),
621+
analytics: fakeAnalytics,
622+
gradleUtils: FakeGradleUtils(),
623+
platform: FakePlatform(),
624+
androidStudio: FakeAndroidStudio(),
625+
);
626+
processManager.addCommand(
627+
const FakeCommand(
628+
command: <String>['gradlew', '-q', 'printNdkVersion'],
629+
stdout: 'NdkVersion: 30.0.12345678\n',
630+
),
631+
);
632+
processManager.addCommand(
633+
const FakeCommand(
634+
command: <String>[
635+
'gradlew',
636+
'-q',
637+
'-Ptarget-platform=android-arm,android-arm64,android-x64',
638+
'-Ptarget=lib/main.dart',
639+
'-Pbase-application-name=android.app.Application',
640+
'-Pdart-obfuscation=false',
641+
'-Ptrack-widget-creation=false',
642+
'-Ptree-shake-icons=false',
643+
'assembleRelease',
644+
],
645+
),
646+
);
647+
648+
fileSystem.file('android/gradlew').createSync(recursive: true);
649+
fileSystem.directory('android').childFile('gradle.properties').createSync(recursive: true);
650+
fileSystem.file('android/build.gradle').createSync(recursive: true);
651+
fileSystem.directory('android').childDirectory('app').childFile('build.gradle')
652+
..createSync(recursive: true)
653+
..writeAsStringSync('apply from: irrelevant/flutter.gradle');
654+
fileSystem
655+
.directory('build')
656+
.childDirectory('app')
657+
.childDirectory('outputs')
658+
.childDirectory('flutter-apk')
659+
.childFile('app-release.apk')
660+
.createSync(recursive: true);
661+
662+
final FlutterProject project = FlutterProject.fromDirectoryTest(
663+
fileSystem.currentDirectory,
664+
);
665+
project.android.appManifestFile
666+
..createSync(recursive: true)
667+
..writeAsStringSync(minimalV2EmbeddingManifest);
668+
669+
await builder.buildGradleApp(
670+
project: project,
671+
androidBuildInfo: const AndroidBuildInfo(
672+
BuildInfo(
673+
BuildMode.release,
674+
null,
675+
treeShakeIcons: false,
676+
packageConfigPath: '.dart_tool/package_config.json',
677+
),
678+
),
679+
target: 'lib/main.dart',
680+
isBuildingBundle: false,
681+
configOnly: false,
682+
localGradleErrors: const <GradleHandledError>[],
683+
);
684+
685+
expect(processManager, hasNoRemainingExpectations);
686+
},
687+
overrides: <Type, Generator>{
688+
AndroidSdk: () {
689+
fileSystem.directory(sdkPath()).createSync(recursive: true);
690+
fileSystem.directory(sdkLicensesPath()).createSync(recursive: true);
691+
fileSystem
692+
.directory(ndkPath('28.2.13676358'))
693+
.childFile('source.properties')
694+
.createSync(recursive: true);
695+
fileSystem
696+
.directory(ndkPath('29.0.13846066'))
697+
.childFile('source.properties')
698+
.createSync(recursive: true);
699+
return AndroidSdk(
700+
fileSystem.directory(sdkPath()),
701+
java: FakeJava(),
702+
fileSystem: fileSystem,
703+
);
704+
},
705+
AndroidStudio: () => FakeAndroidStudio(),
706+
},
707+
);
708+
604709
testUsingContext(
605710
'Can immediately tool exit on recognized exit code/stderr',
606711
() async {
@@ -1457,6 +1562,12 @@ void main() {
14571562
platform: FakePlatform(environment: <String, String>{'HOME': '/home'}),
14581563
androidStudio: FakeAndroidStudio(),
14591564
);
1565+
processManager.addCommand(
1566+
const FakeCommand(
1567+
command: <String>['gradlew', '-q', 'printNdkVersion'],
1568+
stdout: 'NdkVersion: 29.0.13846066\n',
1569+
),
1570+
);
14601571
processManager.addCommand(
14611572
FakeCommand(command: List<String>.of(commonCommandPortion)..add('bundleRelease')),
14621573
);
@@ -1531,6 +1642,12 @@ void main() {
15311642
platform: FakePlatform(environment: <String, String>{'HOME': '/home'}),
15321643
androidStudio: FakeAndroidStudio(),
15331644
);
1645+
processManager.addCommand(
1646+
const FakeCommand(
1647+
command: <String>['gradlew', '-q', 'printNdkVersion'],
1648+
stdout: 'NdkVersion: 29.0.13846066\n',
1649+
),
1650+
);
15341651
processManager.addCommand(
15351652
FakeCommand(command: List<String>.of(commonCommandPortion)..add('bundleRelease')),
15361653
);

0 commit comments

Comments
 (0)