Rework check external dependencies task to check for all kinds of configurations

Test: Checked list of validated artifacts is super set of previously validated artifacts
Change-Id: I99784a40c34632ffba4bd8a9fa6242b7276f9185
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/license/CheckExternalDependencyLicensesTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/license/CheckExternalDependencyLicensesTask.kt
index 902949a..f916624 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/license/CheckExternalDependencyLicensesTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/license/CheckExternalDependencyLicensesTask.kt
@@ -15,6 +15,7 @@
  */
 package androidx.build.license
 
+import androidx.build.capitalize
 import androidx.build.getPrebuiltsRoot
 import androidx.build.getVersionByName
 import androidx.build.kotlinExtensionOrNull
@@ -22,12 +23,12 @@
 import org.gradle.api.DefaultTask
 import org.gradle.api.GradleException
 import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
 import org.gradle.api.artifacts.ExternalDependency
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier
 import org.gradle.api.artifacts.repositories.MavenArtifactRepository
 import org.gradle.api.artifacts.result.ResolvedArtifactResult
-import org.gradle.api.attributes.Category
-import org.gradle.api.attributes.Usage
+import org.gradle.api.attributes.Attribute
 import org.gradle.api.attributes.plugin.GradlePluginApiVersion
 import org.gradle.api.file.ConfigurableFileCollection
 import org.gradle.api.file.FileCollection
@@ -103,7 +104,6 @@
     }
 
     companion object {
-        internal const val CONFIGURATION_NAME = "allExternalDependencies"
         const val TASK_NAME = "checkExternalLicenses"
     }
 }
@@ -113,68 +113,21 @@
         CheckExternalDependencyLicensesTask.TASK_NAME,
         CheckExternalDependencyLicensesTask::class.java
     ) { task ->
+        @OptIn(ExperimentalBuildToolsApi::class, ExperimentalKotlinGradlePluginApi::class)
+        val kotlinVersion =
+            kotlinExtensionOrNull?.compilerVersion?.get() ?: project.getVersionByName("kotlin")
         task.prebuiltsRoot.set(project.provider { project.getPrebuiltsRoot().absolutePath })
-
+        // configurations.toList() to avoid modify the collection while we iterate over it
+        val duplicateConfigs =
+            configurations.toList().map { configuration ->
+                duplicateForLicenseCheck(configuration, kotlinVersion)
+            }
+        val localArtifactRepositories = project.findLocalMavenRepositories()
         task.filesToCheck.from(
-            project.provider {
-                val configName = "CheckExternalLicences"
-                val container = project.configurations
-                val checkerConfig =
-                    container.findByName(configName)
-                        ?: container.create(configName) { checkerConfig ->
-                            checkerConfig.isCanBeConsumed = false
-                            checkerConfig.attributes {
-                                it.attribute(
-                                    Usage.USAGE_ATTRIBUTE,
-                                    project.objects.named<Usage>(Usage.JAVA_RUNTIME)
-                                )
-                                it.attribute(
-                                    Category.CATEGORY_ATTRIBUTE,
-                                    project.objects.named<Category>(Category.LIBRARY)
-                                )
-                                it.attribute(
-                                    GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE,
-                                    project.objects.named<GradlePluginApiVersion>(
-                                        GradleVersion.current().getVersion()
-                                    )
-                                )
-                            }
-
-                            @OptIn(
-                                ExperimentalBuildToolsApi::class,
-                                ExperimentalKotlinGradlePluginApi::class
-                            )
-                            val kotlinVersion =
-                                kotlinExtensionOrNull?.compilerVersion?.get()
-                                    ?: project.getVersionByName("kotlin")
-
-                            project.configurations
-                                .flatMap {
-                                    it.allDependencies
-                                        .filterIsInstance(ExternalDependency::class.java)
-                                        .filterNot { it.group?.startsWith("com.android") == true }
-                                        .filterNot { it.group?.startsWith("android.arch") == true }
-                                        .filterNot { it.group?.startsWith("androidx") == true }
-                                }
-                                .forEach { dep ->
-                                    /* workaround for dependency constraint applied in Kotlin Plugin */
-                                    if (
-                                        dep.group == "org.jetbrains.kotlin" &&
-                                            dep.name == "kotlin-build-tools-impl"
-                                    ) {
-                                        dep.version { it.strictly(kotlinVersion) }
-                                    }
-                                    checkerConfig.dependencies.add(dep)
-                                }
-                        }
-
-                val localArtifactRepositories = project.findLocalMavenRepositories()
-                val dependencyArtifacts =
-                    checkerConfig.incoming.artifacts.artifacts.mapNotNull {
-                        project.validateAndGetArtifactInPrebuilts(it, localArtifactRepositories)
-                    }
-
-                dependencyArtifacts
+            duplicateConfigs.flatMap { configuration ->
+                configuration.incoming.artifacts.artifacts.mapNotNull {
+                    project.validateAndGetArtifactInPrebuilts(it, localArtifactRepositories)
+                }
             }
         )
     }
@@ -249,3 +202,45 @@
             .map { File(it) }
     return project.files(fileList)
 }
+
+private fun Project.duplicateForLicenseCheck(
+    configuration: Configuration,
+    kotlinVersion: String
+): Configuration {
+    val duplicate = configurations.create("${configuration.name}${configurationNameSuffix}")
+    duplicate.copyAttributesFrom(configuration)
+    duplicate.attributes.attribute(
+        GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE,
+        project.objects.named(GradleVersion.current().version)
+    )
+    val dependencies =
+        configuration.dependencies
+            .filterIsInstance<ExternalDependency>()
+            .filter { it.isValidForLicenseCheck() }
+            .onEach { it.fixVersion(kotlinVersion) }
+    duplicate.dependencies.addAll(dependencies)
+    duplicate.isCanBeConsumed = false
+    return duplicate
+}
+
+private fun Configuration.copyAttributesFrom(configuration: Configuration) {
+    configuration.attributes.keySet().forEach { attrKey ->
+        val value: Any = configuration.attributes.getAttribute(attrKey)!!
+        @Suppress("UNCHECKED_CAST") attributes.attribute(attrKey as Attribute<Any>, value)
+    }
+}
+
+private fun ExternalDependency.isValidForLicenseCheck(): Boolean {
+    return group?.startsWith("com.android") == false &&
+        group?.startsWith("android.arch") == false &&
+        group?.startsWith("androidx") == false
+}
+
+private fun ExternalDependency.fixVersion(kotlinVersion: String) {
+    /* workaround for dependency constraint applied in Kotlin Plugin */
+    if (group == "org.jetbrains.kotlin" && name == "kotlin-build-tools-impl") {
+        this.version { version -> version.strictly(kotlinVersion) }
+    }
+}
+
+private val configurationNameSuffix = CheckExternalDependencyLicensesTask.TASK_NAME.capitalize()
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 2d28c739..10f0ff2 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -719,6 +719,11 @@
             <sha256 value="6b55fbe6ffee621454c03df7bea720d189789e136391a524e29506ff40654180" origin="Generated by Gradle" reason="https://github.com/google/guava/issues/7154"/>
          </artifact>
       </component>
+      <component group="com.google.guava" name="guava-parent" version="23.5-jre">
+         <artifact name="guava-parent-23.5-jre.pom">
+            <sha256 value="d69af85990f77ef54b4aa8e744c014de811cad8a62e790b177c219b59c75d918" reason="https://github.com/google/guava/issues/7154"/>
+         </artifact>
+      </component>
       <component group="com.google.j2objc" name="j2objc-annotations" version="3.0.0">
          <artifact name="j2objc-annotations-3.0.0.pom">
             <pgp value="BDB5FA4FE719D787FB3D3197F6D4A1D411E9D1AE"/>
diff --git a/privacysandbox/ads/ads-adservices-java/build.gradle b/privacysandbox/ads/ads-adservices-java/build.gradle
index 305ee1a..ba04170 100644
--- a/privacysandbox/ads/ads-adservices-java/build.gradle
+++ b/privacysandbox/ads/ads-adservices-java/build.gradle
@@ -40,7 +40,7 @@
     api(libs.guavaListenableFuture)
     implementation project(path: ':privacysandbox:ads:ads-adservices')
 
-    androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0'
+    androidTestImplementation(libs.kotlinCoroutinesAndroid)
     androidTestImplementation project(path: ':privacysandbox:ads:ads-adservices')
     androidTestImplementation project(path: ':javascriptengine:javascriptengine')
     androidTestImplementation(libs.junit)