From 17bf4c60fc6a67d5bed52cc67b0ccf9aa4670b62 Mon Sep 17 00:00:00 2001 From: Yifan Yang Date: Fri, 3 Feb 2023 09:49:35 -0800 Subject: [PATCH] Revert "Migrate vendor plugin to new transform api. (#4424)" This reverts commit ffc5d33e693909e3ff3b45479a180c32db17c063. --- .../ktx/src/androidTest/AndroidManifest.xml | 13 + buildSrc/build.gradle.kts | 4 +- .../gradle/plugins/FirebaseLibraryPlugin.java | 14 + .../firebase/gradle/plugins/VendorPlugin.kt | 280 +++++++++++------- .../firebase/gradle/plugins/VendorTests.kt | 167 ++--------- .../ktx/src/androidTest/AndroidManifest.xml | 13 + .../firebase-crashlytics-ndk.gradle | 6 +- .../ktx/src/androidTest/AndroidManifest.xml | 13 + firebase-firestore/firebase-firestore.gradle | 35 ++- .../src/androidTest/AndroidManifest.xml | 6 +- .../ktx/src/androidTest/AndroidManifest.xml | 14 + .../src/androidTest/AndroidManifest.xml | 14 + .../src/androidTest/AndroidManifest.xml | 8 +- .../src/androidTest/AndroidManifest.xml | 26 ++ .../src/androidTest/AndroidManifest.xml | 26 ++ .../transport-runtime.gradle | 6 + 16 files changed, 377 insertions(+), 268 deletions(-) create mode 100644 appcheck/firebase-appcheck/ktx/src/androidTest/AndroidManifest.xml create mode 100644 firebase-appdistribution-api/ktx/src/androidTest/AndroidManifest.xml create mode 100644 firebase-crashlytics/ktx/src/androidTest/AndroidManifest.xml create mode 100644 firebase-functions/ktx/src/androidTest/AndroidManifest.xml create mode 100644 firebase-functions/src/androidTest/AndroidManifest.xml create mode 100644 firebase-installations/src/androidTest/AndroidManifest.xml create mode 100644 firebase-messaging/src/androidTest/AndroidManifest.xml diff --git a/appcheck/firebase-appcheck/ktx/src/androidTest/AndroidManifest.xml b/appcheck/firebase-appcheck/ktx/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..f5b157ca951 --- /dev/null +++ b/appcheck/firebase-appcheck/ktx/src/androidTest/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3641f499b50..ad487a81b0e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -62,8 +62,8 @@ dependencies { implementation("org.eclipse.jgit:org.eclipse.jgit:6.3.0.202209071007-r") implementation("com.google.code.gson:gson:2.8.9") - implementation("com.android.tools.build:gradle:7.4.0") - implementation("com.android.tools.build:builder-test-api:7.4.0") + implementation("com.android.tools.build:gradle:7.2.2") + implementation("com.android.tools.build:builder-test-api:7.2.2") implementation("gradle.plugin.com.github.sherter.google-java-format:google-java-format-gradle-plugin:0.9") testImplementation("junit:junit:4.13.2") diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java index 3b0b998d596..b4b9f89c77a 100644 --- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java +++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java @@ -90,6 +90,20 @@ public void apply(Project project) { test.systemProperty("javax.net.ssl.trustStoreType", "JKS"); }))); + // skip debug tests in CI + // TODO(vkryachko): provide ability for teams to control this if needed + if (System.getenv().containsKey("FIREBASE_CI")) { + android.setTestBuildType("release"); + project + .getTasks() + .all( + task -> { + if ("testDebugUnitTest".equals(task.getName())) { + task.setEnabled(false); + } + }); + } + setupApiInformationAnalysis(project, android); android.testServer(new FirebaseTestServer(project, firebaseLibrary.testLab, android)); diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/VendorPlugin.kt b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/VendorPlugin.kt index 17c9f5b064b..da1a0659fbd 100644 --- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/VendorPlugin.kt +++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/VendorPlugin.kt @@ -14,9 +14,11 @@ package com.google.firebase.gradle.plugins -import com.android.build.api.artifact.ScopedArtifact -import com.android.build.api.variant.LibraryAndroidComponentsExtension -import com.android.build.api.variant.ScopedArtifacts +import com.android.build.api.transform.Format +import com.android.build.api.transform.QualifiedContent +import com.android.build.api.transform.Transform +import com.android.build.api.transform.TransformInvocation +import com.android.build.gradle.LibraryExtension import com.android.build.gradle.LibraryPlugin import java.io.BufferedInputStream import java.io.BufferedOutputStream @@ -26,44 +28,42 @@ import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipFile import java.util.zip.ZipOutputStream -import javax.inject.Inject -import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.file.Directory -import org.gradle.api.file.RegularFile -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty +import org.gradle.api.logging.Logger import org.gradle.api.provider.Property -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction +import org.gradle.api.provider.Provider import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.getByType -import org.gradle.process.ExecOperations + +abstract class VendorExtension { + /** Controls dead code elimination, enabled if true. */ + abstract val optimize: Property + + init { + optimize.convention(true) + } +} class VendorPlugin : Plugin { override fun apply(project: Project) { + val vendorConfig = project.extensions.create("vendor") project.plugins.all { when (this) { - is LibraryPlugin -> configureAndroid(project) + is LibraryPlugin -> configureAndroid(project, vendorConfig) } } } - fun configureAndroid(project: Project) { + fun configureAndroid(project: Project, vendorConfig: VendorExtension) { project.apply(plugin = "LicenseResolverPlugin") val vendor = project.configurations.create("vendor") project.configurations.all { when (name) { - "releaseCompileOnly", - "debugImplementation", + "compileOnly", "testImplementation", "androidTestImplementation" -> extendsFrom(vendor) } @@ -72,63 +72,174 @@ class VendorPlugin : Plugin { val jarJar = project.configurations.create("firebaseJarJarArtifact") project.dependencies.add("firebaseJarJarArtifact", "org.pantsbuild:jarjar:1.7.2") - val androidComponents = project.extensions.getByType() + val android = project.extensions.getByType(LibraryExtension::class.java) + + android.registerTransform( + VendorTransform( + android, + vendor, + JarJarTransformer( + parentPackageProvider = { + android.libraryVariants.find { it.name == "release" }!!.applicationId + }, + jarJarProvider = { jarJar.resolve() }, + project = project, + logger = project.logger, + optimize = vendorConfig.optimize + ), + logger = project.logger + ) + ) + } +} - androidComponents.onVariants(androidComponents.selector().withBuildType("release")) { variant -> - val vendorTask = - project.tasks.register("${variant.name}VendorTransform", VendorTask::class.java) { - vendorDependencies.set(vendor) - packageName.set(variant.namespace) - this.jarJar.set(jarJar) +interface JarTransformer { + fun transform( + inputJar: File, + outputJar: File, + ownPackages: Set, + packagesToVendor: Set + ) +} + +class JarJarTransformer( + private val parentPackageProvider: () -> String, + private val jarJarProvider: () -> Collection, + private val project: Project, + private val logger: Logger, + private val optimize: Provider +) : JarTransformer { + override fun transform( + inputJar: File, + outputJar: File, + ownPackages: Set, + packagesToVendor: Set + ) { + val parentPackage = parentPackageProvider() + val rulesFile = File.createTempFile(parentPackage, ".jarjar") + rulesFile.printWriter().use { + if (optimize.get()) { + for (packageName in ownPackages) { + it.println("keep $packageName.**") } - variant.artifacts - .forScope(ScopedArtifacts.Scope.PROJECT) - .use(vendorTask) - .toTransform( - ScopedArtifact.CLASSES, - VendorTask::inputJars, - VendorTask::inputDirs, - VendorTask::outputJar - ) + } + for (externalPackageName in packagesToVendor) { + it.println("rule $externalPackageName.** $parentPackage.@0") + } } + logger.info("The following JarJar configuration will be used:\n ${rulesFile.readText()}") + + project + .javaexec { + main = "org.pantsbuild.jarjar.Main" + classpath = project.files(jarJarProvider()) + args = + listOf("process", rulesFile.absolutePath, inputJar.absolutePath, outputJar.absolutePath) + systemProperties = mapOf("verbose" to "true", "misplacedClassStrategy" to "FATAL") + } + .assertNormalExitValue() } } -abstract class VendorTask @Inject constructor(private val execOperations: ExecOperations) : - DefaultTask() { - @get:[InputFiles Classpath] - abstract val vendorDependencies: Property +class VendorTransform( + private val android: LibraryExtension, + private val configuration: Configuration, + private val jarTransformer: JarTransformer, + private val logger: Logger +) : Transform() { + override fun getName() = "firebaseVendorTransform" - @get:[InputFiles Classpath] - abstract val jarJar: Property + override fun getInputTypes(): MutableSet { + return mutableSetOf(QualifiedContent.DefaultContentType.CLASSES) + } - @get:Input abstract val packageName: Property + override fun isIncremental() = false - @get:InputFiles abstract val inputJars: ListProperty + override fun getScopes(): MutableSet { + return mutableSetOf(QualifiedContent.Scope.PROJECT) + } - @get:InputFiles abstract val inputDirs: ListProperty + override fun getReferencedScopes(): MutableSet { + return mutableSetOf(QualifiedContent.Scope.PROJECT) + } - @get:OutputFile abstract val outputJar: RegularFileProperty + override fun transform(transformInvocation: TransformInvocation) { + if (configuration.resolve().isEmpty()) { + logger.warn( + "Nothing to vendor. " + + "If you don't need vendor functionality please disable 'firebase-vendor' plugin. " + + "Otherwise use the 'vendor' configuration to add dependencies you want vendored in." + ) + for (input in transformInvocation.inputs) { + for (directoryInput in input.directoryInputs) { + val directoryOutput = + transformInvocation.outputProvider.getContentLocation( + directoryInput.name, + setOf(QualifiedContent.DefaultContentType.CLASSES), + mutableSetOf(QualifiedContent.Scope.PROJECT), + Format.DIRECTORY + ) + directoryInput.file.copyRecursively(directoryOutput, overwrite = true) + } + for (jarInput in input.jarInputs) { + val jarOutput = + transformInvocation.outputProvider.getContentLocation( + jarInput.name, + setOf(QualifiedContent.DefaultContentType.CLASSES), + mutableSetOf(QualifiedContent.Scope.PROJECT), + Format.JAR + ) - @TaskAction - fun taskAction() { - val workDir = File.createTempFile("vendorTmp", null) - workDir.mkdirs() - workDir.deleteRecursively() + jarInput.file.copyTo(jarOutput, overwrite = true) + } + } + return + } + + val contentLocation = + transformInvocation.outputProvider.getContentLocation( + "sourceAndVendoredLibraries", + setOf(QualifiedContent.DefaultContentType.CLASSES), + mutableSetOf(QualifiedContent.Scope.PROJECT), + Format.DIRECTORY + ) + contentLocation.deleteRecursively() + contentLocation.mkdirs() + val tmpDir = File(contentLocation, "tmp") + tmpDir.mkdirs() + try { + val fatJar = process(tmpDir, transformInvocation) + unzipJar(fatJar, contentLocation) + } finally { + tmpDir.deleteRecursively() + } + } + + private fun isTest(transformInvocation: TransformInvocation): Boolean { + return android.testVariants.find { it.name == transformInvocation.context.variantName } != null + } + private fun process(workDir: File, transformInvocation: TransformInvocation): File { + transformInvocation.context.variantName val unzippedDir = File(workDir, "unzipped") - val externalCodeDir = unzippedDir + val unzippedExcludedDir = File(workDir, "unzipped-excluded") + unzippedDir.mkdirs() + unzippedExcludedDir.mkdirs() - for (directory in inputDirs.get()) { - directory.asFile.copyRecursively(unzippedDir) - } - for (jar in inputJars.get()) { - unzipJar(jar.asFile, unzippedDir) + val externalCodeDir = if (isTest(transformInvocation)) unzippedExcludedDir else unzippedDir + + for (input in transformInvocation.inputs) { + for (directoryInput in input.directoryInputs) { + directoryInput.file.copyRecursively(unzippedDir) + } + for (jarInput in input.jarInputs) { + unzipJar(jarInput.file, unzippedDir) + } } val ownPackageNames = inferPackages(unzippedDir) - for (jar in vendorDependencies.get()) { + for (jar in configuration.resolve()) { unzipJar(jar, externalCodeDir) } val externalPackageNames = inferPackages(externalCodeDir) subtract ownPackageNames @@ -139,55 +250,24 @@ abstract class VendorTask @Inject constructor(private val execOperations: ExecOp throw GradleException( "Vendoring java or javax packages is not supported. " + "Please exclude one of the direct or transitive dependencies: \n" + - vendorDependencies - .get() - .resolvedConfiguration - .resolvedArtifacts - .joinToString(separator = "\n") + configuration.resolvedConfiguration.resolvedArtifacts.joinToString(separator = "\n") ) } - val jar = File(workDir, "intermediate.jar") zipAll(unzippedDir, jar) - transform(jar, ownPackageNames, externalPackageNames) - } + val outputJar = File(workDir, "output.jar") - fun transform(inputJar: File, ownPackages: Set, packagesToVendor: Set) { - val parentPackage = packageName.get() - val rulesFile = File.createTempFile(parentPackage, ".jarjar") - rulesFile.printWriter().use { - for (packageName in ownPackages) { - it.println("keep $packageName.**") - } - for (externalPackageName in packagesToVendor) { - it.println("rule $externalPackageName.** $parentPackage.@0") - } - } - logger.info("The following JarJar configuration will be used:\n ${rulesFile.readText()}") - - execOperations - .javaexec { - mainClass.set("org.pantsbuild.jarjar.Main") - classpath = project.files(jarJar.get()) - args = - listOf( - "process", - rulesFile.absolutePath, - inputJar.absolutePath, - outputJar.asFile.get().absolutePath - ) - systemProperties = mapOf("verbose" to "true", "misplacedClassStrategy" to "FATAL") - } - .assertNormalExitValue() + jarTransformer.transform(jar, outputJar, ownPackageNames, externalPackageNames) + return outputJar } -} -fun inferPackages(dir: File): Set { - return dir - .walk() - .filter { it.name.endsWith(".class") } - .map { it.parentFile.toRelativeString(dir).replace('/', '.') } - .toSet() + private fun inferPackages(dir: File): Set { + return dir + .walk() + .filter { it.name.endsWith(".class") } + .map { it.parentFile.toRelativeString(dir).replace('/', '.') } + .toSet() + } } fun unzipJar(jar: File, directory: File) { diff --git a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/VendorTests.kt b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/VendorTests.kt index b95720668a2..de722c12f75 100644 --- a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/VendorTests.kt +++ b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/VendorTests.kt @@ -28,13 +28,11 @@ import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.junit.runners.JUnit4 -private fun manifest(packageName: String, content: String = "") = +private const val MANIFEST = """ - - $content - + package="com.example"> + """ @@ -123,83 +121,37 @@ class VendorPluginTests { val classes = buildWith( """ - implementation 'javax.inject:javax.inject:1' - vendor ('com.google.dagger:dagger:2.43.2') { + vendor ('com.google.dagger:dagger:2.27') { exclude group: "javax.inject", module: "javax.inject" } - annotationProcessor 'com.google.dagger:dagger-compiler:2.43.2' """ .trimIndent(), - SourceFile( - name = "com/example/MyComponent.java", - content = - """ - package com.example; - - import dagger.Component; - import javax.inject.Singleton; - - @Component - @Singleton - interface MyComponent { - Hello getHello(); - } - """ - .trimIndent() - ), SourceFile( name = "com/example/Hello.java", content = """ package com.example; - import javax.inject.Inject; - import javax.inject.Singleton; + import dagger.Module; - @Singleton + @Module public class Hello { - @Inject - Hello() {} - - public void method() {} - - public static Hello newInstance() { - return DaggerMyComponent.create().getHello(); - } + public static void main(String[] args) {} } """ .trimIndent() - ), - mainActivityCode = "com.example.Hello.newInstance().method();", - manifestEntries = - """ - - - - - - - """ - .trimIndent() + ) ) // expected classes assertThat(classes) .containsAtLeast( "com/example/Hello.class", "com/example/BuildConfig.class", - "com/example/dagger/Component.class", - "com/example/dagger/internal/Preconditions.class", + "com/example/dagger/Module.class" ) } - private fun buildWith( - deps: String, - vararg files: SourceFile, - mainActivityCode: String = "", - manifestEntries: String = "" - ): List { + private fun buildWith(deps: String, vararg files: SourceFile): List { testProjectDir .newFile("build.gradle") .writeText( @@ -210,84 +162,7 @@ class VendorPluginTests { jcenter() } } - """ - .trimIndent() - ) - testProjectDir.newFile("gradle.properties").writeText("android.r8.failOnMissingClasses=true") - testProjectDir - .newFile("settings.gradle") - .writeText( - """ - rootProject.name = 'testlib' - include 'mylib' - include 'myapp' - """ - .trimIndent() - ) - - testProjectDir.newFolder("myapp/src/main/java") - testProjectDir.newFolder("myapp/src/main/java/com/example/app") - testProjectDir - .newFile("myapp/src/main/java/com/example/app/MainActivity.java") - .writeText( - """ - package com.example.app; - - import android.app.Activity; - import android.os.Bundle; - - public class MainActivity extends Activity { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - $mainActivityCode - } - } - """ - .trimIndent() - ) - testProjectDir - .newFile("myapp/src/main/AndroidManifest.xml") - .writeText(manifest("com.example.app", content = manifestEntries)) - testProjectDir - .newFile("myapp/build.gradle") - .writeText( - """ - plugins { - id 'com.android.application' - } - repositories { - google() - jcenter() - } - - android { - compileSdk = 26 - defaultConfig { - minSdk = 14 - } - buildTypes { - release { - minifyEnabled = true - proguardFiles getDefaultProguardFile("proguard-android-optimize.txt") - } - } - } - - dependencies { - implementation project(':mylib') - } - """ - .trimIndent() - ) - - testProjectDir.newFolder("mylib/src/main/java") - testProjectDir.newFile("mylib/src/main/AndroidManifest.xml").writeText(manifest("com.example")) - testProjectDir - .newFile("mylib/build.gradle") - .writeText( - """ - plugins { + plugins { id 'com.android.library' id 'firebase-vendor' } @@ -296,12 +171,7 @@ class VendorPluginTests { jcenter() } - android { - compileSdk = 26 - defaultConfig { - minSdk = 14 - } - } + android.compileSdkVersion = 26 dependencies { $deps @@ -309,19 +179,24 @@ class VendorPluginTests { """ .trimIndent() ) + testProjectDir.newFile("settings.gradle").writeText("rootProject.name = 'testlib'") + + testProjectDir.newFolder("src/main/java") + testProjectDir.newFile("src/main/AndroidManifest.xml").writeText(MANIFEST) for (file in files) { - File(testProjectDir.root, "mylib/src/main/java/${Paths.get(file.name).parent}").mkdirs() - testProjectDir.newFile("mylib/src/main/java/${file.name}").writeText(file.content) + // if (1+1 == 2) {throw RuntimeException("src/main/java/${Paths.get(file.name).parent}")} + testProjectDir.newFolder("src/main/java/${Paths.get(file.name).parent}") + testProjectDir.newFile("src/main/java/${file.name}").writeText(file.content) } GradleRunner.create() - .withArguments(":mylib:assemble", ":myapp:assemble") + .withArguments("assemble") .withProjectDir(testProjectDir.root) .withPluginClasspath() .build() - val aarFile = File(testProjectDir.root, "mylib/build/outputs/aar/mylib-release.aar") + val aarFile = File(testProjectDir.root, "build/outputs/aar/testlib-release.aar") assertThat(aarFile.exists()).isTrue() val zipFile = ZipFile(aarFile) diff --git a/firebase-appdistribution-api/ktx/src/androidTest/AndroidManifest.xml b/firebase-appdistribution-api/ktx/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..dec011f3e13 --- /dev/null +++ b/firebase-appdistribution-api/ktx/src/androidTest/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/firebase-crashlytics-ndk/firebase-crashlytics-ndk.gradle b/firebase-crashlytics-ndk/firebase-crashlytics-ndk.gradle index 2268a62d90a..035dc852962 100644 --- a/firebase-crashlytics-ndk/firebase-crashlytics-ndk.gradle +++ b/firebase-crashlytics-ndk/firebase-crashlytics-ndk.gradle @@ -75,7 +75,6 @@ android { tasks.register("fixTrampolineFilenames${variant.baseName}${arch}", com.google.firebase.gradle.NdkBinaryFixTask) { it.inputFile = file("${buildDir}/intermediates/ndkBuild/${variant.baseName}/obj/local/${arch}/crashlytics-trampoline") - it.dependsOn(variant.externalNativeBuildProviders) } } @@ -88,6 +87,11 @@ android { } } } + tasks.findAll { + it.name.startsWith("externalNativeBuild") && !it.name.contains("Clean") + }.each { task -> + fixTasks.each { fix -> fix.configure { it.dependsOn task } } + } } } diff --git a/firebase-crashlytics/ktx/src/androidTest/AndroidManifest.xml b/firebase-crashlytics/ktx/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..4a6be17cfd1 --- /dev/null +++ b/firebase-crashlytics/ktx/src/androidTest/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/firebase-firestore/firebase-firestore.gradle b/firebase-firestore/firebase-firestore.gradle index 03f7521dcdf..2f1a727e9be 100644 --- a/firebase-firestore/firebase-firestore.gradle +++ b/firebase-firestore/firebase-firestore.gradle @@ -49,9 +49,6 @@ protobuf { } } } -// Acceptable values are: 'emulator', 'qa', 'nightly', and 'prod'. -ext.targetBackend = 'emulator' - android { adbOptions { timeOutInMs 60 * 1000 @@ -65,19 +62,6 @@ android { multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'proguard.txt' - - if (findProperty("useProdBackendForTests")) { - buildConfigField("boolean", "USE_EMULATOR_FOR_TESTS", "false") - } else { - buildConfigField("boolean", "USE_EMULATOR_FOR_TESTS", "true") - } - - if (findProperty('targetBackend')) { - buildConfigField("String", "TARGET_BACKEND", "\"${property("targetBackend")}\"") - } else { - // By default set the target backend to 'emulator' - buildConfigField("String", "TARGET_BACKEND", "\"emulator\"") - } } sourceSets { @@ -105,12 +89,31 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } testOptions.unitTests.includeAndroidResources = true + + // Acceptable values are: 'emulator', 'qa', 'nightly', and 'prod'. + ext.targetBackend = 'emulator' } tasks.withType(Test) { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 } +android.libraryVariants.all { variant -> + if (findProperty('targetBackend')) { + variant.buildConfigField("String", "TARGET_BACKEND", "\"${property("targetBackend")}\"") + } else { + // By default set the target backend to 'emulator' + variant.buildConfigField("String", "TARGET_BACKEND", "\"emulator\"") + } + + def localProps = new Properties() + + try { + file("local.properties").withInputStream { localProps.load(it) } + } catch (FileNotFoundException e) { + } +} + googleJavaFormat { exclude 'src/testUtil/java/com/google/firebase/firestore/testutil/Assert.java' exclude 'src/testUtil/java/com/google/firebase/firestore/testutil/ThrowingRunnable.java' diff --git a/firebase-firestore/src/androidTest/AndroidManifest.xml b/firebase-firestore/src/androidTest/AndroidManifest.xml index 66a5f4c34a9..89bee0097c0 100644 --- a/firebase-firestore/src/androidTest/AndroidManifest.xml +++ b/firebase-firestore/src/androidTest/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.google.firebase.firestore"> @@ -9,4 +9,8 @@ + + diff --git a/firebase-functions/ktx/src/androidTest/AndroidManifest.xml b/firebase-functions/ktx/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..e00dc0c7ec9 --- /dev/null +++ b/firebase-functions/ktx/src/androidTest/AndroidManifest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/firebase-functions/src/androidTest/AndroidManifest.xml b/firebase-functions/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..a607dbb15d1 --- /dev/null +++ b/firebase-functions/src/androidTest/AndroidManifest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/firebase-inappmessaging/src/androidTest/AndroidManifest.xml b/firebase-inappmessaging/src/androidTest/AndroidManifest.xml index a2f12f62066..90249ec338c 100644 --- a/firebase-inappmessaging/src/androidTest/AndroidManifest.xml +++ b/firebase-inappmessaging/src/androidTest/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.google.firebase.inappmessaging"> - + + + diff --git a/firebase-installations/src/androidTest/AndroidManifest.xml b/firebase-installations/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..f9fb55a7b56 --- /dev/null +++ b/firebase-installations/src/androidTest/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/firebase-messaging/src/androidTest/AndroidManifest.xml b/firebase-messaging/src/androidTest/AndroidManifest.xml new file mode 100644 index 00000000000..f8e83dd5006 --- /dev/null +++ b/firebase-messaging/src/androidTest/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/transport/transport-runtime/transport-runtime.gradle b/transport/transport-runtime/transport-runtime.gradle index 0cf73913d41..36ad7a35aad 100644 --- a/transport/transport-runtime/transport-runtime.gradle +++ b/transport/transport-runtime/transport-runtime.gradle @@ -64,6 +64,12 @@ firebaseLibrary { } } +vendor { + // Integration tests use dagger classes that are not used in the main SDK, + // so we disable dead code elimination to ensure those classes are preserved. + optimize = false +} + android { compileSdkVersion project.targetSdkVersion defaultConfig {