From aa230140e76e7eedaced6e91661a16475db205db Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Fri, 12 May 2023 15:16:06 -0700 Subject: [PATCH] Add namespace to Android plugin templates (#126354) Adds the `namespace` property necessary for AGP 8 compatibility to the plugin templates, with the conditional logic to ensure that it doesn't break AGP <4.2, so that new plugins will be maximally compatible. Part of https://github.com/flutter/flutter/issues/125181 --- .../android-java.tmpl/build.gradle.tmpl | 4 ++ .../android-kotlin.tmpl/build.gradle.tmpl | 4 ++ .../plugin_ffi/android.tmpl/build.gradle.tmpl | 4 ++ .../commands.shard/permeable/create_test.dart | 71 +++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/packages/flutter_tools/templates/plugin/android-java.tmpl/build.gradle.tmpl b/packages/flutter_tools/templates/plugin/android-java.tmpl/build.gradle.tmpl index 26f3272c92..b3359741f3 100644 --- a/packages/flutter_tools/templates/plugin/android-java.tmpl/build.gradle.tmpl +++ b/packages/flutter_tools/templates/plugin/android-java.tmpl/build.gradle.tmpl @@ -22,6 +22,10 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { + if (project.android.hasProperty("namespace")) { + namespace '{{androidIdentifier}}' + } + compileSdkVersion {{compileSdkVersion}} compileOptions { diff --git a/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/build.gradle.tmpl b/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/build.gradle.tmpl index 9b35a39f38..b466c607ee 100644 --- a/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/build.gradle.tmpl +++ b/packages/flutter_tools/templates/plugin/android-kotlin.tmpl/build.gradle.tmpl @@ -25,6 +25,10 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { + if (project.android.hasProperty("namespace")) { + namespace '{{androidIdentifier}}' + } + compileSdkVersion 31 compileOptions { diff --git a/packages/flutter_tools/templates/plugin_ffi/android.tmpl/build.gradle.tmpl b/packages/flutter_tools/templates/plugin_ffi/android.tmpl/build.gradle.tmpl index 0383cfd737..74511b59ce 100644 --- a/packages/flutter_tools/templates/plugin_ffi/android.tmpl/build.gradle.tmpl +++ b/packages/flutter_tools/templates/plugin_ffi/android.tmpl/build.gradle.tmpl @@ -25,6 +25,10 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { + if (project.android.hasProperty("namespace")) { + namespace '{{androidIdentifier}}' + } + // Bumping the plugin compileSdkVersion requires all clients of this plugin // to bump the version in their app. compileSdkVersion {{compileSdkVersion}} diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart index 0249996e11..6d86f2a953 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart @@ -2848,6 +2848,77 @@ void main() { expect(buildContent.contains('targetSdkVersion flutter.targetSdkVersion'), true); }); + testUsingContext('Android Java plugin contains namespace', () async { + Cache.flutterRoot = '../..'; + + final CreateCommand command = CreateCommand(); + final CommandRunner runner = createTestCommandRunner(command); + + await runner.run(['create', '--no-pub', + '-t', 'plugin', + '--org', 'com.bar.foo', + '-a', 'java', + '--platforms=android', + projectDir.path]); + + final File buildGradleFile = globals.fs.file('${projectDir.path}/android/build.gradle'); + + expect(buildGradleFile.existsSync(), true); + + final String buildGradleContent = await buildGradleFile.readAsString(); + + expect(buildGradleContent.contains("namespace 'com.bar.foo.flutter_project'"), true); + // The namespace should be conditionalized for AGP <4.2. + expect(buildGradleContent.contains('if (project.android.hasProperty("namespace")) {'), true); + }); + + testUsingContext('Android FFI plugin contains namespace', () async { + Cache.flutterRoot = '../..'; + + final CreateCommand command = CreateCommand(); + final CommandRunner runner = createTestCommandRunner(command); + + await runner.run(['create', '--no-pub', + '-t', 'plugin_ffi', + '--org', 'com.bar.foo', + '--platforms=android', + projectDir.path]); + + final File buildGradleFile = globals.fs.file('${projectDir.path}/android/build.gradle'); + + expect(buildGradleFile.existsSync(), true); + + final String buildGradleContent = await buildGradleFile.readAsString(); + + expect(buildGradleContent.contains("namespace 'com.bar.foo.flutter_project'"), true); + // The namespace should be conditionalized for AGP <4.2. + expect(buildGradleContent.contains('if (project.android.hasProperty("namespace")) {'), true); + }); + + testUsingContext('Android Kotlin plugin contains namespace', () async { + Cache.flutterRoot = '../..'; + + final CreateCommand command = CreateCommand(); + final CommandRunner runner = createTestCommandRunner(command); + + await runner.run(['create', '--no-pub', + '-t', 'plugin', + '--org', 'com.bar.foo', + '-a', 'kotlin', + '--platforms=android', + projectDir.path]); + + final File buildGradleFile = globals.fs.file('${projectDir.path}/android/build.gradle'); + + expect(buildGradleFile.existsSync(), true); + + final String buildGradleContent = await buildGradleFile.readAsString(); + + expect(buildGradleContent.contains("namespace 'com.bar.foo.flutter_project'"), true); + // The namespace should be conditionalized for AGP <4.2. + expect(buildGradleContent.contains('if (project.android.hasProperty("namespace")) {'), true); + }); + testUsingContext('Linux plugins handle partially camel-case project names correctly', () async { Cache.flutterRoot = '../..';