From eabed2381b3f4d155d3f58386e26e1401d4a413f Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Wed, 4 Dec 2024 11:45:43 -0500 Subject: [PATCH] Add deprecation notice for Android x86 when building for the target (#159750) Related to https://github.com/flutter/flutter/issues/157543 --- .../flutter_tools/lib/src/android/gradle.dart | 15 ++++ .../flutter_tools/lib/src/build_info.dart | 2 + .../android/android_gradle_builder_test.dart | 79 +++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart index 9dcb8f0df8..f2cc1e95f8 100644 --- a/packages/flutter_tools/lib/src/android/gradle.dart +++ b/packages/flutter_tools/lib/src/android/gradle.dart @@ -122,6 +122,11 @@ String getAarTaskFor(BuildInfo buildInfo) { return _taskFor('assembleAar', buildInfo); } +@visibleForTesting +const String androidX86DeprecationWarning = + 'Support for Android x86 targets will be removed in the next stable release after 3.27. ' + 'See https://github.com/flutter/flutter/issues/157543 for details.'; + /// Returns the output APK file names for a given [AndroidBuildInfo]. /// /// For example, when [splitPerAbi] is true, multiple APKs are created. @@ -188,6 +193,13 @@ class AndroidGradleBuilder implements AndroidBuilder { // Module projects artifacts are located in `build/host`. outputDirectory = outputDirectory.childDirectory('host'); } + + final bool containsX86Targets = androidBuildInfo.where( + (AndroidBuildInfo info) => info.containsX86Target, + ).isNotEmpty; + if (containsX86Targets) { + _logger.printWarning(androidX86DeprecationWarning); + } for (final AndroidBuildInfo androidBuildInfo in androidBuildInfo) { await buildGradleAar( project: project, @@ -300,6 +312,9 @@ class AndroidGradleBuilder implements AndroidBuilder { int retry = 0, @visibleForTesting int? maxRetries, }) async { + if (androidBuildInfo.containsX86Target) { + _logger.printWarning(androidX86DeprecationWarning); + } if (!project.android.isSupportedVersion) { _exitWithUnsupportedProjectMessage(_logger.terminal, _analytics); } diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index 50e076beaa..842a6373d9 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart @@ -396,6 +396,8 @@ class AndroidBuildInfo { /// The target platforms for the build. final Iterable targetArchs; + bool get containsX86Target => targetArchs.contains(AndroidArch.x86); + /// Whether to bootstrap an empty application. final bool fastStart; } diff --git a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart index 36f40a750e..a80a0e336e 100644 --- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart @@ -811,6 +811,85 @@ void main() { AndroidStudio: () => FakeAndroidStudio(), }); + testUsingContext('prints deprecation warning when building for x86', () async { + // See https://github.com/flutter/flutter/issues/157543 for details. + final AndroidGradleBuilder builder = AndroidGradleBuilder( + java: FakeJava(), + logger: logger, + processManager: processManager, + fileSystem: fileSystem, + artifacts: Artifacts.test(), + analytics: fakeAnalytics, + gradleUtils: FakeGradleUtils(), + platform: FakePlatform(), + androidStudio: FakeAndroidStudio(), + ); + processManager.addCommand(const FakeCommand( + command: [ + 'gradlew', + '-q', + '-Ptarget-platform=android-x86', + '-Ptarget=lib/main.dart', + '-Pbase-application-name=android.app.Application', + '-Pdart-obfuscation=false', + '-Ptrack-widget-creation=false', + '-Ptree-shake-icons=false', + 'assembleRelease', + ], + )); + fileSystem.directory('android') + .childFile('build.gradle') + .createSync(recursive: true); + + fileSystem.directory('android') + .childFile('gradle.properties') + .createSync(recursive: true); + + fileSystem.directory('android') + .childDirectory('app') + .childFile('build.gradle') + ..createSync(recursive: true) + ..writeAsStringSync('apply from: irrelevant/flutter.gradle'); + + fileSystem.directory('build') + .childDirectory('app') + .childDirectory('outputs') + .childDirectory('flutter-apk') + .childFile('app-release.apk') + .createSync(recursive: true); + + final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); + project.android.appManifestFile + ..createSync(recursive: true) + ..writeAsStringSync(minimalV2EmbeddingManifest); + + await builder.buildGradleApp( + project: project, + androidBuildInfo: const AndroidBuildInfo( + BuildInfo( + BuildMode.release, + null, + treeShakeIcons: false, + packageConfigPath: '.dart_tool/package_config.json', + ), + targetArchs: [AndroidArch.x86], + ), + target: 'lib/main.dart', + isBuildingBundle: false, + configOnly: false, + localGradleErrors: const [], + ); + + expect( + logger.statusText, + contains('Built build/app/outputs/flutter-apk/app-release.apk (0.0MB)'), + ); + expect(logger.warningText, contains(androidX86DeprecationWarning)); + expect(processManager, hasNoRemainingExpectations); + }, overrides: { + AndroidStudio: () => FakeAndroidStudio(), + }); + testUsingContext('Uses namespace attribute if manifest lacks a package attribute', () async { final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory); final AndroidSdk sdk = FakeAndroidSdk();