Ensure apps can build while using AGP 3.3.0 (#71964) (#72754)
Co-authored-by: Emmanuel Garcia <egarciad@google.com>
diff --git a/dev/devicelab/bin/tasks/android_plugin_example_app_build_test.dart b/dev/devicelab/bin/tasks/android_plugin_example_app_build_test.dart
index 469a4d0..e15f02e 100644
--- a/dev/devicelab/bin/tasks/android_plugin_example_app_build_test.dart
+++ b/dev/devicelab/bin/tasks/android_plugin_example_app_build_test.dart
@@ -15,7 +15,6 @@
/// Tests that a plugin example app can be built using the current Flutter Gradle plugin.
Future<void> main() async {
await task(() async {
-
section('Find Java');
final String javaHome = await findJavaHome();
@@ -32,22 +31,47 @@
options: <String>['--android', '--no-ios'],
);
- final Directory tempDir = Directory.systemTemp.createTempSync('flutter_plugin_test.');
- final Directory projectDir = Directory(path.join(tempDir.path, 'plugin_test'));
+ final Directory tempDir =
+ Directory.systemTemp.createTempSync('flutter_plugin_test.');
+ final Directory projectDir =
+ Directory(path.join(tempDir.path, 'plugin_test'));
try {
await inDirectory(tempDir, () async {
await flutter(
'create',
- options: <String>['--template=plugin', '--platforms=android', 'plugin_test'],
+ options: <String>[
+ '--template=plugin',
+ '--platforms=android',
+ 'plugin_test',
+ ],
);
});
- final Directory exampleAppDir = Directory(path.join(projectDir.path, 'example'));
+ final Directory exampleAppDir =
+ Directory(path.join(projectDir.path, 'example'));
if (!exists(exampleAppDir)) {
return TaskResult.failure('Example app directory doesn\'t exist');
}
- section('Run flutter build apk');
+ final File buildGradleFile =
+ File(path.join(exampleAppDir.path, 'android', 'build.gradle'));
+
+ if (!exists(buildGradleFile)) {
+ return TaskResult.failure('$buildGradleFile doesn\'t exist');
+ }
+
+ final String buildGradle = buildGradleFile.readAsStringSync();
+ final RegExp androidPluginRegExp =
+ RegExp(r'com\.android\.tools\.build:gradle:(\d+\.\d+\.\d+)');
+
+ section('Use AGP 4.1.0');
+
+ String newBuildGradle = buildGradle.replaceAll(
+ androidPluginRegExp, 'com.android.tools.build:gradle:4.1.0');
+ print(newBuildGradle);
+ buildGradleFile.writeAsString(newBuildGradle);
+
+ section('Run flutter build apk using AGP 4.1.0');
await inDirectory(exampleAppDir, () async {
await flutter(
@@ -72,6 +96,55 @@
return TaskResult.failure('Failed to build app-release.apk');
}
+ section('Clean');
+
+ await inDirectory(exampleAppDir, () async {
+ await flutter('clean');
+ });
+
+ section('Remove Gradle wrapper');
+
+ Directory(path.join(exampleAppDir.path, 'android', 'gradle', 'wrapper'))
+ .deleteSync(recursive: true);
+
+ section('Use AGP 3.3.0');
+
+ newBuildGradle = buildGradle.replaceAll(
+ androidPluginRegExp, 'com.android.tools.build:gradle:3.3.0');
+ print(newBuildGradle);
+ buildGradleFile.writeAsString(newBuildGradle);
+
+ section('Enable R8 in gradle.properties');
+
+ final File gradleProperties =
+ File(path.join(exampleAppDir.path, 'android', 'gradle.properties'));
+
+ if (!exists(gradleProperties)) {
+ return TaskResult.failure('$gradleProperties doesn\'t exist');
+ }
+
+ gradleProperties.writeAsString('''
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+android.enableR8=true''');
+
+ section('Run flutter build apk using AGP 3.3.0');
+
+ await inDirectory(exampleAppDir, () async {
+ await flutter(
+ 'build',
+ options: <String>[
+ 'apk',
+ '--target-platform=android-arm',
+ ],
+ );
+ });
+
+ if (!exists(File(exampleApk))) {
+ return TaskResult.failure('Failed to build app-release.apk');
+ }
+
return TaskResult.success(null);
} on TaskResult catch (taskResult) {
return taskResult;
diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle
index 579cdea..8ea1ea2 100644
--- a/packages/flutter_tools/gradle/flutter.gradle
+++ b/packages/flutter_tools/gradle/flutter.gradle
@@ -20,6 +20,7 @@
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.bundling.Jar
+import org.gradle.util.VersionNumber
buildscript {
repositories {
@@ -304,7 +305,7 @@
project.dependencies {
implementation pluginProject
}
- Closure addEmbeddingCompileOnlyDependency = { buildType ->
+ Closure addEmbeddingDependencyToPlugin = { buildType ->
String flutterBuildMode = buildModeFor(buildType)
// In AGP 3.5, the embedding must be added as an API implementation,
// so java8 features are desugared against the runtime classpath.
@@ -317,17 +318,39 @@
pluginProject.android.buildTypes {
"${buildType.name}" {}
}
- pluginProject.dependencies.add(
- "${buildType.name}CompileOnly",
- "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
+ // The embedding is a compileOnly dependency of a Flutter plugin,
+ // however prior to Gradle 6.0.0, it must be an API dependency.
+ //
+ // Not doing so, causes transitive dependency resolution conflicts.
+ // That is, the embedding dependencies resolved in the plugin are
+ // different than the ones resolved in the app.
+ if (isGradleVersionGraterOrEqualThan('6.0.0')) {
+ addCompileOnlyDependency(
+ pluginProject,
+ buildType.name,
+ "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion"
+ )
+ } else {
+ addApiDependencies(
+ pluginProject,
+ buildType.name,
+ "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion"
+ )
+ }
}
// Wait until the Android plugin loaded.
pluginProject.afterEvaluate {
- project.android.buildTypes.each addEmbeddingCompileOnlyDependency
- project.android.buildTypes.whenObjectAdded addEmbeddingCompileOnlyDependency
+ project.android.buildTypes.each addEmbeddingDependencyToPlugin
+ project.android.buildTypes.whenObjectAdded addEmbeddingDependencyToPlugin
}
}
+ // Returns `true` if the current Gradle version is greater or equal to the given version.
+ private isGradleVersionGraterOrEqualThan(String version) {
+ return VersionNumber.parse(project.gradle.gradleVersion)
+ .compareTo(VersionNumber.parse(version)) >= 0
+ }
+
// Returns `true` if the given path contains an `android/build.gradle` file.
//
// TODO(egarciad): Fix https://github.com/flutter/flutter/issues/39657.