summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Edgar <lukeedgar@google.com>2022-07-06 11:50:59 +0100
committerLuke Edgar <lukeedgar@google.com>2022-08-11 15:29:45 +0000
commit06f144793051babca37f4c6477bc7c3046defde9 (patch)
tree872692e4630f30c9e0db732b913206251a8e33d4
parentc0cfeebfd54a864cfe7b92187eefdf8a96accaee (diff)
downloadbase-06f144793051babca37f4c6477bc7c3046defde9.tar.gz
Remove AbstractFusedLibraryPlugin and AbstractPrivacySandboxPlugin
Removes abstract classes extended by FusedLibraryPlugin and PrivacySandboxSdkPlugin. Introduces a utility file to share common logic across the plugins. Bug: N/a Test: Existing pass (no behaviour changes) Change-Id: Ied47d4c2023228df88040c7b909685f9471118bb
-rwxr-xr-xbuild-system/gradle-core/lint_baseline.xml112
-rw-r--r--build-system/gradle-core/src/main/java/com/android/build/gradle/internal/fusedlibrary/FusedLibraryPluginUtils.kt73
-rw-r--r--build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractFusedLibraryPlugin.kt302
-rw-r--r--build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractPrivacySandboxPlugin.kt251
-rw-r--r--build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt318
-rw-r--r--build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt244
6 files changed, 562 insertions, 738 deletions
diff --git a/build-system/gradle-core/lint_baseline.xml b/build-system/gradle-core/lint_baseline.xml
index b616cbaac8..ee9bee39ac 100755
--- a/build-system/gradle-core/lint_baseline.xml
+++ b/build-system/gradle-core/lint_baseline.xml
@@ -56,22 +56,6 @@
id="AvoidByLazy"
message="Avoid `by lazy` for simple lazy initialization">
<location
- file="src/main/java/com/android/build/gradle/internal/plugins/AbstractFusedLibraryPlugin.kt"
- line="56"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
- file="src/main/java/com/android/build/gradle/internal/plugins/AbstractPrivacySandboxPlugin.kt"
- line="56"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
file="src/main/java/com/android/build/gradle/internal/test/AbstractTestDataImpl.kt"
line="66"/>
</issue>
@@ -161,7 +145,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/api/component/analytics/AnalyticsEnabledTestVariant.kt"
- line="89"/>
+ line="82"/>
</issue>
<issue
@@ -177,7 +161,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/plugins/AndroidPluginBaseServices.kt"
- line="56"/>
+ line="54"/>
</issue>
<issue
@@ -185,7 +169,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/plugins/AndroidPluginBaseServices.kt"
- line="62"/>
+ line="60"/>
</issue>
<issue
@@ -193,7 +177,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/plugins/AndroidPluginBaseServices.kt"
- line="75"/>
+ line="73"/>
</issue>
<issue
@@ -201,7 +185,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/plugins/AndroidPluginBaseServices.kt"
- line="98"/>
+ line="96"/>
</issue>
<issue
@@ -608,22 +592,6 @@
id="AvoidByLazy"
message="Avoid `by lazy` for simple lazy initialization">
<location
- file="src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt"
- line="55"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
- file="src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt"
- line="63"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
file="src/main/java/com/android/build/gradle/internal/fusedlibrary/FusedLibraryVariantScopeImpl.kt"
line="37"/>
</issue>
@@ -689,7 +657,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/api/variant/impl/LibraryVariantImpl.kt"
- line="121"/>
+ line="120"/>
</issue>
<issue
@@ -713,7 +681,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/ide/v2/NativeModelBuilder.kt"
- line="64"/>
+ line="71"/>
</issue>
<issue
@@ -721,7 +689,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/ide/v2/NativeModelBuilder.kt"
- line="68"/>
+ line="75"/>
</issue>
<issue
@@ -745,23 +713,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt"
- line="59"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
- file="src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt"
- line="75"/>
- </issue>
-
- <issue
- id="AvoidByLazy"
- message="Avoid `by lazy` for simple lazy initialization">
- <location
- file="src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt"
- line="94"/>
+ line="92"/>
</issue>
<issue
@@ -961,7 +913,7 @@
message="Avoid `by lazy` for simple lazy initialization">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="142"/>
+ line="151"/>
</issue>
<issue
@@ -1073,7 +1025,7 @@
message="Do not use `java.nio.file.Files.copy(Path, Path)`. Instead, use `FileUtils.copyFile(Path, Path)` or Kotlin&apos;s `File#copyTo(File)`">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/AsarToApksTransform.kt"
- line="72"/>
+ line="73"/>
</issue>
<issue
@@ -1081,7 +1033,7 @@
message="This reference is unused: name">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/DependencyReportTask.kt"
- line="49"/>
+ line="51"/>
</issue>
<issue
@@ -1089,7 +1041,7 @@
message="This reference is unused: name">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/DependencyReportTask.kt"
- line="56"/>
+ line="58"/>
</issue>
<issue
@@ -1137,7 +1089,7 @@
message="This reference is unused: testApplicationId">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="216"/>
+ line="225"/>
</issue>
<issue
@@ -1145,7 +1097,7 @@
message="This reference is unused: testApplicationId">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="312"/>
+ line="321"/>
</issue>
<issue
@@ -1153,7 +1105,7 @@
message="This reference is unused: testInstrumentationRunner">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="484"/>
+ line="493"/>
</issue>
<issue
@@ -1161,7 +1113,7 @@
message="This reference is unused: testHandleProfiling">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="527"/>
+ line="536"/>
</issue>
<issue
@@ -1169,7 +1121,7 @@
message="This reference is unused: testFunctionalTest">
<location
file="src/main/java/com/android/build/gradle/internal/core/VariantDslInfoImpl.kt"
- line="548"/>
+ line="557"/>
</issue>
<issue
@@ -1177,7 +1129,7 @@
message="Avoid using `org.gradle.api.Project.exec` as it is incompatible with Gradle instant execution.">
<location
file="src/main/java/com/android/build/gradle/internal/ide/v2/NativeModelBuilder.kt"
- line="56"/>
+ line="63"/>
</issue>
<issue
@@ -1201,7 +1153,7 @@
message="This method should only be accessed from tests or within private scope">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/featuresplit/FeatureSetMetadataWriterTask.kt"
- line="127"/>
+ line="130"/>
</issue>
<issue
@@ -1217,7 +1169,7 @@
message="This method should only be accessed from tests or within private scope">
<location
file="src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkMergeDexTask.kt"
- line="58"/>
+ line="61"/>
</issue>
<issue
@@ -1225,7 +1177,7 @@
message="This method should only be accessed from tests or within private scope">
<location
file="src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkMergeDexTask.kt"
- line="60"/>
+ line="63"/>
</issue>
<issue
@@ -1249,7 +1201,7 @@
message="Use `Integer.valueOf(index)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="79"/>
+ line="81"/>
</issue>
<issue
@@ -1257,7 +1209,7 @@
message="Use `Integer.valueOf(libraryList.size)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="102"/>
+ line="104"/>
</issue>
<issue
@@ -1265,7 +1217,7 @@
message="Use `Integer.valueOf(origIndex)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="112"/>
+ line="114"/>
</issue>
<issue
@@ -1273,7 +1225,7 @@
message="Use `Integer.valueOf(libraryDep.libraryIndex)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="117"/>
+ line="119"/>
</issue>
<issue
@@ -1281,7 +1233,7 @@
message="Use `Integer.valueOf(depIndex)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="120"/>
+ line="122"/>
</issue>
<issue
@@ -1289,7 +1241,7 @@
message="Use `Integer.valueOf(depIndex)` instead">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleReportDependenciesTask.kt"
- line="133"/>
+ line="135"/>
</issue>
<issue
@@ -1409,7 +1361,7 @@
message="Avoid using common ForkJoinPool, directly or indirectly (for example via CompletableFuture). It has a limited set of threads on some machines which leads to hangs. See `go/do-not-freeze`.">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/AsarToApksTransform.kt"
- line="77"/>
+ line="78"/>
</issue>
<issue
@@ -1417,7 +1369,7 @@
message="Avoid using common ForkJoinPool, directly or indirectly (for example via CompletableFuture). It has a limited set of threads on some machines which leads to hangs. See `go/do-not-freeze`.">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleToApkTask.kt"
- line="111"/>
+ line="113"/>
</issue>
<issue
@@ -1425,7 +1377,7 @@
message="Avoid using common ForkJoinPool, directly or indirectly (for example via CompletableFuture). It has a limited set of threads on some machines which leads to hangs. See `go/do-not-freeze`.">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/BundleToStandaloneApkTask.kt"
- line="124"/>
+ line="126"/>
</issue>
<issue
@@ -1449,7 +1401,7 @@
message="Avoid using new ForkJoinPool instances when possible. Prefer using the IntelliJ application pool via `com.intellij.openapi.application.Application#executeOnPooledThread`, or for the Android Gradle Plugin use `com.android.build.gradle.internal.tasks.Workers`. See `go/do-not-freeze`.">
<location
file="src/main/java/com/android/build/gradle/internal/tasks/DexMergingTask.kt"
- line="797"/>
+ line="799"/>
</issue>
</issues>
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/fusedlibrary/FusedLibraryPluginUtils.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/fusedlibrary/FusedLibraryPluginUtils.kt
new file mode 100644
index 0000000000..c7d5659334
--- /dev/null
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/fusedlibrary/FusedLibraryPluginUtils.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.build.gradle.internal.fusedlibrary
+
+import com.android.build.api.artifact.Artifact
+import com.android.build.api.artifact.impl.ArtifactsImpl
+import com.android.build.api.attributes.BuildTypeAttr
+import com.android.build.gradle.internal.DependencyConfigurator
+import com.android.build.gradle.internal.SdkComponentsBuildService
+import com.android.build.gradle.internal.publishing.AndroidArtifacts
+import com.android.build.gradle.internal.services.DslServices
+import com.android.build.gradle.internal.services.DslServicesImpl
+import com.android.build.gradle.internal.services.ProjectServices
+import com.android.build.gradle.internal.tasks.factory.TaskCreationAction
+import com.android.build.gradle.internal.tasks.factory.TaskFactoryImpl
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.component.ComponentIdentifier
+import org.gradle.api.attributes.Usage
+import org.gradle.api.file.RegularFile
+import org.gradle.api.provider.Provider
+import org.gradle.api.specs.Spec
+
+fun createTasks(
+ project: Project,
+ artifacts: ArtifactsImpl,
+ artifactForPublication: Artifact.Single<RegularFile>,
+ tasksCreationActions: List<TaskCreationAction<out DefaultTask>>
+) {
+ val taskProviders = TaskFactoryImpl(project.tasks).let { taskFactory ->
+ tasksCreationActions.map { creationAction ->
+ taskFactory.register(creationAction)
+ }
+ }
+
+ // create anchor tasks
+ project.tasks.register("assemble") { assembleTask ->
+ artifactForPublication?.let { artifactTypeForPublication ->
+ assembleTask.dependsOn(artifacts.get(artifactTypeForPublication))
+ } ?: taskProviders.forEach { assembleTask.dependsOn(it) }
+ }
+}
+
+fun configureTransforms(project: Project, projectServices: ProjectServices) {
+ DependencyConfigurator(project, projectServices)
+ .configureGeneralTransforms(namespacedAndroidResources = false)
+}
+
+fun getDslServices(project: Project, projectServices: ProjectServices): DslServices {
+ val sdkComponentsBuildService: Provider<SdkComponentsBuildService> =
+ SdkComponentsBuildService.RegistrationAction(
+ project,
+ projectServices.projectOptions
+ ).execute()
+
+ return DslServicesImpl(projectServices, sdkComponentsBuildService)
+}
+
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractFusedLibraryPlugin.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractFusedLibraryPlugin.kt
deleted file mode 100644
index 88a62d7070..0000000000
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractFusedLibraryPlugin.kt
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.build.gradle.internal.plugins
-
-import com.android.build.api.artifact.Artifact
-import com.android.build.api.attributes.BuildTypeAttr
-import com.android.build.gradle.internal.DependencyConfigurator
-import com.android.build.gradle.internal.SdkComponentsBuildService
-import com.android.build.gradle.internal.fusedlibrary.FusedLibraryVariantScope
-import com.android.build.gradle.internal.fusedlibrary.SegregatingConstraintHandler
-import com.android.build.gradle.internal.publishing.AndroidArtifacts
-import com.android.build.gradle.internal.services.Aapt2DaemonBuildService
-import com.android.build.gradle.internal.services.Aapt2ThreadPoolBuildService
-import com.android.build.gradle.internal.services.DslServicesImpl
-import com.android.build.gradle.internal.tasks.factory.TaskCreationAction
-import com.android.build.gradle.internal.tasks.factory.TaskFactoryImpl
-import com.google.wireless.android.sdk.stats.GradleBuildProfileSpan
-import groovy.namespace.QName
-import groovy.util.Node
-import org.gradle.api.DefaultTask
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.artifacts.ArtifactCollection
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.artifacts.component.LibraryBinaryIdentifier
-import org.gradle.api.artifacts.component.ModuleComponentIdentifier
-import org.gradle.api.artifacts.component.ProjectComponentIdentifier
-import org.gradle.api.attributes.Usage
-import org.gradle.api.component.SoftwareComponentFactory
-import org.gradle.api.file.RegularFile
-import org.gradle.api.provider.Provider
-import org.gradle.api.publish.maven.MavenPom
-import org.gradle.api.publish.maven.MavenPublication
-import org.gradle.build.event.BuildEventsListenerRegistry
-import org.gradle.internal.component.external.model.ModuleComponentArtifactIdentifier
-
-abstract class AbstractFusedLibraryPlugin (
- protected val softwareComponentFactory: SoftwareComponentFactory,
- listenerRegistry: BuildEventsListenerRegistry,
-): AndroidPluginBaseServices(listenerRegistry), Plugin<Project> {
-
- val dslServices by lazy {
- withProject("dslServices") { project ->
- val sdkComponentsBuildService: Provider<SdkComponentsBuildService> =
- SdkComponentsBuildService.RegistrationAction(
- project,
- projectServices.projectOptions
- ).execute()
-
- DslServicesImpl(
- projectServices,
- sdkComponentsBuildService
- )
- }
- }
-
- abstract val variantScope: FusedLibraryVariantScope
-
- internal fun createTasks(
- project: Project,
- variantScope: FusedLibraryVariantScope,
- tasksCreationActions: List<TaskCreationAction<out DefaultTask>>,
- ) {
- configureTransforms(project)
- val taskProviders = TaskFactoryImpl(project.tasks).let { taskFactory ->
- tasksCreationActions.map { creationAction ->
- taskFactory.register(creationAction)
- }
- }
-
- // create anchor tasks
- project.tasks.register("assemble") { assembleTask ->
- artifactForPublication?.let { artifactTypeForPublication ->
- assembleTask.dependsOn(variantScope.artifacts.get(artifactTypeForPublication))
- } ?: taskProviders.forEach { assembleTask.dependsOn(it) }
- }
- }
-
- /**
- * Returns the artifact type that will be used for maven publication or null if nothing is to
- * be published to maven.
- */
- abstract val artifactForPublication: Artifact.Single<RegularFile>?
-
- abstract val artifactTypeForPublication: AndroidArtifacts.ArtifactType
-
- override fun apply(project: Project) {
- super.basePluginApply(project)
-
- // so far by default, we consume and publish only 'debug' variant
-
- // 'include' is the configuration that users will use to indicate which dependencies should
- // be fused.
- val includeConfigurations = project.configurations.create("include").also {
- it.isCanBeConsumed = false
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
- }
-
- // This is the internal configuration that will be used to feed tasks that require access
- // to the resolved 'include' dependency. It is for JAVA_API usage which mean all transitive
- // dependencies that are implementation() scoped will not be included.
- val includeApiClasspath = project.configurations.create("includeApiClasspath").also {
- it.isCanBeConsumed = false
- it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_API)
- )
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
- it.extendsFrom(includeConfigurations)
- }
- variantScope.incomingConfigurations.addConfiguration(includeApiClasspath)
-
- // This is the configuration that will contain all the JAVA_API dependencies that are not
- // fused in the resulting aar library.
- val includedApiUnmerged = project.configurations.create("includeApiUnmerged").also {
- it.isCanBeConsumed = true
- it.isCanBeResolved = true
- it.incoming.beforeResolve(
- SegregatingConstraintHandler(
- includeApiClasspath,
- it,
- variantScope.mergeSpec,
- project,
- )
- )
- }
-
- // This is the internal configuration that will be used to feed tasks that require access
- // to the resolved 'include' dependency. It is for JAVA_RUNTIME usage which mean all transitive
- // dependencies that are implementation() scoped will be included.
- val includeRuntimeClasspath = project.configurations.create("includeRuntimeClasspath").also {
- it.isCanBeConsumed = false
- it.isCanBeResolved = true
-
- it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
- )
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
-
- it.extendsFrom(includeConfigurations)
- }
- variantScope.incomingConfigurations.addConfiguration(includeRuntimeClasspath)
-
- // This is the configuration that will contain all the JAVA_RUNTIME dependencies that are
- // not fused in the resulting aar library.
- val includeRuntimeUnmerged = project.configurations.create("includeRuntimeUnmerged").also {
- it.isCanBeConsumed = false
- it.isCanBeResolved = true
- it.incoming.beforeResolve(
- SegregatingConstraintHandler(
- includeConfigurations,
- it,
- variantScope.mergeSpec,
- project,
- )
- )
- }
-
- // we are only interested in the last provider in the chain of transformers for this bundle.
- // Obviously, this is theoretical at this point since there is no variant API to replace
- // artifacts, there is always only one.
- val bundleTaskProvider = artifactForPublication?.let {
- variantScope
- .artifacts
- .getArtifactContainer(it)
- .getTaskProviders()
- .last()
- }
-
- // this is the outgoing configuration for JAVA_API scoped declarations, it will contain
- // this module and all transitive non merged dependencies
-
- fun configureApiRuntimeElements(elements: Configuration) {
- elements.isCanBeResolved = false
- elements.isCanBeConsumed = true
- elements.isTransitive = true
-
- if (bundleTaskProvider != null) {
- elements.outgoing.variants { variants ->
- variants.create(artifactTypeForPublication.type) {variant ->
- variant.artifact(bundleTaskProvider) { artifact ->
- artifact.type = artifactTypeForPublication.type
- }
- }
- }
- }
- }
-
- val includeApiElements = project.configurations.create("apiElements") { apiElements ->
- configureApiRuntimeElements(apiElements)
- apiElements.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_API)
- )
- apiElements.extendsFrom(includedApiUnmerged)
- }
-
- // this is the outgoing configuration for JAVA_RUNTIME scoped declarations, it will contain
- // this module and all transitive non merged dependencies
- val includeRuntimeElements = project.configurations.create("runtimeElements") { runtimeElements ->
- configureApiRuntimeElements(runtimeElements)
- runtimeElements.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
- )
- runtimeElements.extendsFrom(includeRuntimeUnmerged)
- }
-
- maybePublishToMaven(
- project,
- includeApiElements,
- includeRuntimeElements,
- includeRuntimeUnmerged
- )
- }
-
- override fun configureProject(project: Project) {
- val projectOptions = projectServices.projectOptions
- Aapt2ThreadPoolBuildService.RegistrationAction(project, projectOptions).execute()
- Aapt2DaemonBuildService.RegistrationAction(project, projectOptions).execute()
- }
-
- protected abstract fun maybePublishToMaven(
- project: Project,
- includeApiElements: Configuration,
- includeRuntimeElements: Configuration,
- includeRuntimeUnmerged: Configuration
- )
-
- fun component(
- publication: MavenPublication,
- unmergedArtifacts: ArtifactCollection,
- ) {
-
- publication.pom { pom: MavenPom ->
- pom.withXml { xml ->
- val dependenciesNode = xml.asNode().let {
- it.children().firstOrNull { node ->
- ((node as Node).name() as QName).qualifiedName == "dependencies"
- } ?: it.appendNode("dependencies")
- } as Node
-
- unmergedArtifacts.forEach { artifact ->
- if (artifact.id is ModuleComponentArtifactIdentifier) {
- when (val moduleIdentifier = artifact.id.componentIdentifier) {
- is ModuleComponentIdentifier -> {
- val dependencyNode = dependenciesNode.appendNode("dependency")
- dependencyNode.appendNode("groupId", moduleIdentifier.group)
- dependencyNode.appendNode("artifactId", moduleIdentifier.module)
- dependencyNode.appendNode("version", moduleIdentifier.version)
- dependencyNode.appendNode("scope", "runtime")
- }
- is ProjectComponentIdentifier -> println("Project : ${moduleIdentifier.projectPath}")
- is LibraryBinaryIdentifier -> println("Library : ${moduleIdentifier.projectPath}")
- else -> println("Unknown dependency ${moduleIdentifier.javaClass} : $artifact")
- }
- } else {
- println("Unknown module ${artifact.id.javaClass} : ${artifact.id}")
- }
- }
- }
- }
- }
-
- fun configureTransforms(project: Project) {
- configuratorService.recordBlock(
- GradleBuildProfileSpan.ExecutionType.ARTIFACT_TRANSFORM,
- project.path,
- null
- ) {
- DependencyConfigurator(project, projectServices)
- .configureGeneralTransforms(namespacedAndroidResources = false)
- }
- }
-}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractPrivacySandboxPlugin.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractPrivacySandboxPlugin.kt
deleted file mode 100644
index eb252ab2d4..0000000000
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/AbstractPrivacySandboxPlugin.kt
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.build.gradle.internal.plugins
-
-import com.android.build.api.artifact.Artifact
-import com.android.build.api.attributes.BuildTypeAttr
-import com.android.build.gradle.internal.DependencyConfigurator
-import com.android.build.gradle.internal.SdkComponentsBuildService
-import com.android.build.gradle.internal.fusedlibrary.FusedLibraryVariantScope
-import com.android.build.gradle.internal.fusedlibrary.SegregatingConstraintHandler
-import com.android.build.gradle.internal.privaysandboxsdk.PrivacySandboxSdkVariantScope
-import com.android.build.gradle.internal.publishing.AndroidArtifacts
-import com.android.build.gradle.internal.services.Aapt2DaemonBuildService
-import com.android.build.gradle.internal.services.Aapt2ThreadPoolBuildService
-import com.android.build.gradle.internal.services.DslServicesImpl
-import com.android.build.gradle.internal.tasks.factory.TaskCreationAction
-import com.android.build.gradle.internal.tasks.factory.TaskFactoryImpl
-import com.google.wireless.android.sdk.stats.GradleBuildProfileSpan
-import groovy.namespace.QName
-import groovy.util.Node
-import org.gradle.api.DefaultTask
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.artifacts.ArtifactCollection
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.artifacts.component.LibraryBinaryIdentifier
-import org.gradle.api.artifacts.component.ModuleComponentIdentifier
-import org.gradle.api.artifacts.component.ProjectComponentIdentifier
-import org.gradle.api.attributes.Usage
-import org.gradle.api.component.SoftwareComponentFactory
-import org.gradle.api.file.RegularFile
-import org.gradle.api.provider.Provider
-import org.gradle.api.publish.maven.MavenPom
-import org.gradle.api.publish.maven.MavenPublication
-import org.gradle.build.event.BuildEventsListenerRegistry
-import org.gradle.internal.component.external.model.ModuleComponentArtifactIdentifier
-
-abstract class AbstractPrivacySandboxPlugin(
- listenerRegistry: BuildEventsListenerRegistry,
-): AndroidPluginBaseServices(listenerRegistry), Plugin<Project> {
-
- val dslServices by lazy {
- withProject("dslServices") { project ->
- val sdkComponentsBuildService: Provider<SdkComponentsBuildService> =
- SdkComponentsBuildService.RegistrationAction(
- project,
- projectServices.projectOptions
- ).execute()
-
- DslServicesImpl(
- projectServices,
- sdkComponentsBuildService
- )
- }
- }
-
- abstract val variantScope: PrivacySandboxSdkVariantScope
-
- internal fun createTasks(
- project: Project,
- variantScope: PrivacySandboxSdkVariantScope,
- tasksCreationActions: List<TaskCreationAction<out DefaultTask>>,
- ) {
- configureTransforms(project)
- val taskProviders = TaskFactoryImpl(project.tasks).let { taskFactory ->
- tasksCreationActions.map { creationAction ->
- taskFactory.register(creationAction)
- }
- }
-
- // create anchor tasks
- project.tasks.register("assemble") { assembleTask ->
- artifactForPublication?.let { artifactTypeForPublication ->
- assembleTask.dependsOn(variantScope.artifacts.get(artifactTypeForPublication))
- } ?: taskProviders.forEach { assembleTask.dependsOn(it) }
- }
- }
-
- /**
- * Returns the artifact type that will be used for maven publication or null if nothing is to
- * be published to maven.
- */
- internal abstract val artifactForPublication: Artifact.Single<RegularFile>?
-
- internal abstract val artifactTypeForPublication: AndroidArtifacts.ArtifactType
-
- override fun apply(project: Project) {
- super.basePluginApply(project)
-
- // so far by default, we consume and publish only 'debug' variant
-
- // 'include' is the configuration that users will use to indicate which dependencies should
- // be fused.
- val includeConfigurations = project.configurations.create("include").also {
- it.isCanBeConsumed = false
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
- }
-
- // This is the internal configuration that will be used to feed tasks that require access
- // to the resolved 'include' dependency. It is for JAVA_API usage which mean all transitive
- // dependencies that are implementation() scoped will not be included.
- val includeApiClasspath = project.configurations.create("includeApiClasspath").also {
- it.isCanBeConsumed = false
- it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_API)
- )
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
- it.extendsFrom(includeConfigurations)
- }
- variantScope.incomingConfigurations.addConfiguration(includeApiClasspath)
-
- // This is the configuration that will contain all the JAVA_API dependencies that are not
- // fused in the resulting aar library.
- val includedApiUnmerged = project.configurations.create("includeApiUnmerged").also {
- it.isCanBeConsumed = true
- it.isCanBeResolved = true
- it.incoming.beforeResolve(
- SegregatingConstraintHandler(
- includeApiClasspath,
- it,
- variantScope.mergeSpec,
- project,
- )
- )
- }
-
- // This is the internal configuration that will be used to feed tasks that require access
- // to the resolved 'include' dependency. It is for JAVA_RUNTIME usage which mean all transitive
- // dependencies that are implementation() scoped will be included.
- val includeRuntimeClasspath = project.configurations.create("includeRuntimeClasspath").also {
- it.isCanBeConsumed = false
- it.isCanBeResolved = true
-
- it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
- )
- val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
- it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- buildType,
- )
-
- it.extendsFrom(includeConfigurations)
- }
- variantScope.incomingConfigurations.addConfiguration(includeRuntimeClasspath)
-
- // This is the configuration that will contain all the JAVA_RUNTIME dependencies that are
- // not fused in the resulting aar library.
- val includeRuntimeUnmerged = project.configurations.create("includeRuntimeUnmerged").also {
- it.isCanBeConsumed = false
- it.isCanBeResolved = true
- it.incoming.beforeResolve(
- SegregatingConstraintHandler(
- includeConfigurations,
- it,
- variantScope.mergeSpec,
- project,
- )
- )
- }
-
- // we are only interested in the last provider in the chain of transformers for this bundle.
- // Obviously, this is theoretical at this point since there is no variant API to replace
- // artifacts, there is always only one.
- val bundleTaskProvider = artifactForPublication?.let {
- variantScope
- .artifacts
- .getArtifactContainer(it)
- .getTaskProviders()
- .last()
- }
-
- // this is the outgoing configuration for JAVA_API scoped declarations, it will contain
- // this module and all transitive non merged dependencies
-
- fun configureApiRuntimeElements(elements: Configuration) {
- elements.isCanBeResolved = false
- elements.isCanBeConsumed = true
- elements.isTransitive = true
-
- if (bundleTaskProvider != null) {
- elements.outgoing.variants { variants ->
- variants.create(artifactTypeForPublication.type) {variant ->
- variant.artifact(bundleTaskProvider) { artifact ->
- artifact.type = artifactTypeForPublication.type
- }
- }
- }
- }
- }
-
- val includeApiElements = project.configurations.create("apiElements") { apiElements ->
- configureApiRuntimeElements(apiElements)
- apiElements.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_API)
- )
- }
-
- // this is the outgoing configuration for JAVA_RUNTIME scoped declarations, it will contain
- // this module and all transitive non merged dependencies
- val includeRuntimeElements = project.configurations.create("runtimeElements") { runtimeElements ->
- configureApiRuntimeElements(runtimeElements)
- runtimeElements.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
- )
- }
- }
-
- override fun configureProject(project: Project) {
- val projectOptions = projectServices.projectOptions
- Aapt2ThreadPoolBuildService.RegistrationAction(project, projectOptions).execute()
- Aapt2DaemonBuildService.RegistrationAction(project, projectOptions).execute()
- }
-
- private fun configureTransforms(project: Project) {
- configuratorService.recordBlock(
- GradleBuildProfileSpan.ExecutionType.ARTIFACT_TRANSFORM,
- project.path,
- null
- ) {
- DependencyConfigurator(project, projectServices)
- .configureGeneralTransforms(namespacedAndroidResources = false)
- }
- }
-}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt
index 560172ad3e..a98dc55c71 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/FusedLibraryPlugin.kt
@@ -17,23 +17,37 @@
package com.android.build.gradle.internal.plugins
import com.android.build.api.artifact.Artifact
+import com.android.build.api.artifact.impl.ArtifactsImpl
import com.android.build.api.attributes.BuildTypeAttr
import com.android.build.api.dsl.FusedLibraryExtension
import com.android.build.gradle.internal.dsl.FusedLibraryExtensionImpl
import com.android.build.gradle.internal.fusedlibrary.FusedLibraryInternalArtifactType
+import com.android.build.gradle.internal.fusedlibrary.FusedLibraryVariantScope
import com.android.build.gradle.internal.fusedlibrary.FusedLibraryVariantScopeImpl
+import com.android.build.gradle.internal.fusedlibrary.SegregatingConstraintHandler
+import com.android.build.gradle.internal.fusedlibrary.configureTransforms
+import com.android.build.gradle.internal.fusedlibrary.createTasks
+import com.android.build.gradle.internal.fusedlibrary.getDslServices
import com.android.build.gradle.internal.publishing.AndroidArtifacts
+import com.android.build.gradle.internal.services.DslServices
import com.android.build.gradle.internal.tasks.MergeJavaResourceTask
import com.android.build.gradle.tasks.FusedLibraryBundleAar
import com.android.build.gradle.tasks.FusedLibraryBundleClasses
-import com.android.build.gradle.tasks.FusedLibraryMergeClasses
import com.android.build.gradle.tasks.FusedLibraryClassesRewriteTask
import com.android.build.gradle.tasks.FusedLibraryManifestMergerTask
import com.android.build.gradle.tasks.FusedLibraryMergeArtifactTask
+import com.android.build.gradle.tasks.FusedLibraryMergeClasses
import com.android.build.gradle.tasks.FusedLibraryMergeResourcesTask
import com.google.wireless.android.sdk.stats.GradleBuildProject
+import groovy.namespace.QName
+import groovy.util.Node
+import org.gradle.api.Plugin
import org.gradle.api.Project
+import org.gradle.api.artifacts.ArtifactCollection
import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.component.LibraryBinaryIdentifier
+import org.gradle.api.artifacts.component.ModuleComponentIdentifier
+import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.LibraryElements
@@ -41,18 +55,25 @@ import org.gradle.api.attributes.Usage
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.file.RegularFile
import org.gradle.api.publish.PublishingExtension
+import org.gradle.api.publish.maven.MavenPom
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.build.event.BuildEventsListenerRegistry
+import org.gradle.internal.component.external.model.ModuleComponentArtifactIdentifier
import javax.inject.Inject
@Suppress("UnstableApiUsage")
class FusedLibraryPlugin @Inject constructor(
- softwareComponentFactory: SoftwareComponentFactory,
- listenerRegistry: BuildEventsListenerRegistry,
-): AbstractFusedLibraryPlugin(softwareComponentFactory, listenerRegistry) {
+ private val softwareComponentFactory: SoftwareComponentFactory,
+ listenerRegistry: BuildEventsListenerRegistry,
+) : AndroidPluginBaseServices(listenerRegistry), Plugin<Project> {
+
+ val dslServices: DslServices by lazy(LazyThreadSafetyMode.NONE) {
+ withProject("dslServices") { project ->
+ getDslServices(project, projectServices)
+ }
+ }
- // so far, there is only one variant.
- override val variantScope by lazy {
+ private val variantScope: FusedLibraryVariantScope by lazy(LazyThreadSafetyMode.NONE) {
withProject("variantScope") { project ->
FusedLibraryVariantScopeImpl(
project
@@ -60,45 +81,48 @@ class FusedLibraryPlugin @Inject constructor(
}
}
- private val extension: FusedLibraryExtension by lazy {
+ private val extension: FusedLibraryExtension by lazy(LazyThreadSafetyMode.NONE) {
withProject("extension") { project ->
instantiateExtension(project)
}
}
+ override fun configureProject(project: Project) {
+ }
+
override fun configureExtension(project: Project) {
extension
}
private fun instantiateExtension(project: Project): FusedLibraryExtension {
- val fusedLibraryExtensionImpl= dslServices.newDecoratedInstance(
- FusedLibraryExtensionImpl::class.java,
- dslServices,
+ val fusedLibraryExtensionImpl = dslServices.newDecoratedInstance(
+ FusedLibraryExtensionImpl::class.java,
+ dslServices,
)
abstract class Extension(
- val publicExtensionImpl: FusedLibraryExtensionImpl,
+ val publicExtensionImpl: FusedLibraryExtensionImpl,
): FusedLibraryExtension by publicExtensionImpl
return project.extensions.create(
- FusedLibraryExtension::class.java,
- "android",
- Extension::class.java,
- fusedLibraryExtensionImpl
+ FusedLibraryExtension::class.java,
+ "android",
+ Extension::class.java,
+ fusedLibraryExtensionImpl
)
}
- override fun maybePublishToMaven(
- project: Project,
- includeApiElements: Configuration,
- includeRuntimeElements: Configuration,
- includeRuntimeUnmerged: Configuration
+ private fun maybePublishToMaven(
+ project: Project,
+ includeApiElements: Configuration,
+ includeRuntimeElements: Configuration,
+ includeRuntimeUnmerged: Configuration
) {
val bundleTaskProvider = variantScope
.artifacts
- .getArtifactContainer(artifactForPublication)
+ .getArtifactContainer(FusedLibraryInternalArtifactType.BUNDLED_LIBRARY)
.getTaskProviders()
.last()
@@ -107,27 +131,27 @@ class FusedLibraryPlugin @Inject constructor(
it.isCanBeResolved = false
it.isVisible = false
it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_API)
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_API)
)
it.attributes.attribute(
- Bundling.BUNDLING_ATTRIBUTE,
- project.objects.named(Bundling::class.java, Bundling.EXTERNAL)
+ Bundling.BUNDLING_ATTRIBUTE,
+ project.objects.named(Bundling::class.java, Bundling.EXTERNAL)
)
it.attributes.attribute(
- Category.CATEGORY_ATTRIBUTE,
- project.objects.named(Category::class.java, Category.LIBRARY)
+ Category.CATEGORY_ATTRIBUTE,
+ project.objects.named(Category::class.java, Category.LIBRARY)
)
it.attributes.attribute(
- LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
- project.objects.named(
- LibraryElements::class.java,
- AndroidArtifacts.ArtifactType.AAR.type
- )
+ LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
+ project.objects.named(
+ LibraryElements::class.java,
+ AndroidArtifacts.ArtifactType.AAR.type
+ )
)
it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- project.objects.named(BuildTypeAttr::class.java, "debug")
+ BuildTypeAttr.ATTRIBUTE,
+ project.objects.named(BuildTypeAttr::class.java, "debug")
)
it.extendsFrom(includeApiElements)
variantScope.outgoingConfigurations.addConfiguration(it)
@@ -141,27 +165,27 @@ class FusedLibraryPlugin @Inject constructor(
it.isCanBeResolved = false
it.isVisible = false
it.attributes.attribute(
- Usage.USAGE_ATTRIBUTE,
- project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
)
it.attributes.attribute(
- Bundling.BUNDLING_ATTRIBUTE,
- project.objects.named(Bundling::class.java, Bundling.EXTERNAL)
+ Bundling.BUNDLING_ATTRIBUTE,
+ project.objects.named(Bundling::class.java, Bundling.EXTERNAL)
)
it.attributes.attribute(
- Category.CATEGORY_ATTRIBUTE,
- project.objects.named(Category::class.java, Category.LIBRARY)
+ Category.CATEGORY_ATTRIBUTE,
+ project.objects.named(Category::class.java, Category.LIBRARY)
)
it.attributes.attribute(
- LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
- project.objects.named(
- LibraryElements::class.java,
- AndroidArtifacts.ArtifactType.AAR.type
- )
+ LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
+ project.objects.named(
+ LibraryElements::class.java,
+ AndroidArtifacts.ArtifactType.AAR.type
+ )
)
it.attributes.attribute(
- BuildTypeAttr.ATTRIBUTE,
- project.objects.named(BuildTypeAttr::class.java, "debug")
+ BuildTypeAttr.ATTRIBUTE,
+ project.objects.named(BuildTypeAttr::class.java, "debug")
)
it.extendsFrom(includeRuntimeElements)
variantScope.outgoingConfigurations.addConfiguration(it)
@@ -185,19 +209,52 @@ class FusedLibraryPlugin @Inject constructor(
project.afterEvaluate {
project.extensions.findByType(PublishingExtension::class.java)?.also {
component(
- it.publications.create("maven", MavenPublication::class.java)
- .also { mavenPublication ->
- mavenPublication.from(adhocComponent)
- }, includeRuntimeUnmerged.incoming.artifacts
+ it.publications.create("maven", MavenPublication::class.java)
+ .also { mavenPublication ->
+ mavenPublication.from(adhocComponent)
+ }, includeRuntimeUnmerged.incoming.artifacts
)
}
}
}
+ fun component(publication: MavenPublication, unmergedArtifacts: ArtifactCollection) {
+ publication.pom { pom: MavenPom ->
+ pom.withXml { xml ->
+ val dependenciesNode = xml.asNode().let {
+ it.children().firstOrNull { node ->
+ ((node as Node).name() as QName).qualifiedName == "dependencies"
+ } ?: it.appendNode("dependencies")
+ } as Node
+
+ unmergedArtifacts.forEach { artifact ->
+ if (artifact.id is ModuleComponentArtifactIdentifier) {
+ when (val moduleIdentifier = artifact.id.componentIdentifier) {
+ is ModuleComponentIdentifier -> {
+ val dependencyNode = dependenciesNode.appendNode("dependency")
+ dependencyNode.appendNode("groupId", moduleIdentifier.group)
+ dependencyNode.appendNode("artifactId", moduleIdentifier.module)
+ dependencyNode.appendNode("version", moduleIdentifier.version)
+ dependencyNode.appendNode("scope", "runtime")
+ }
+ is ProjectComponentIdentifier -> println("Project : ${moduleIdentifier.projectPath}")
+ is LibraryBinaryIdentifier -> println("Library : ${moduleIdentifier.projectPath}")
+ else -> println("Unknown dependency ${moduleIdentifier.javaClass} : $artifact")
+ }
+ } else {
+ println("Unknown module ${artifact.id.javaClass} : ${artifact.id}")
+ }
+ }
+ }
+ }
+ }
+
override fun createTasks(project: Project) {
+ configureTransforms(project, projectServices)
createTasks(
project,
- variantScope,
+ variantScope.artifacts,
+ FusedLibraryInternalArtifactType.BUNDLED_LIBRARY,
listOf(
FusedLibraryClassesRewriteTask.CreationAction(variantScope),
FusedLibraryManifestMergerTask.CreationAction(variantScope),
@@ -210,12 +267,157 @@ class FusedLibraryPlugin @Inject constructor(
)
}
- override fun getAnalyticsPluginType(): GradleBuildProject.PluginType =
- GradleBuildProject.PluginType.FUSED_LIBRARIES
+ override fun getAnalyticsPluginType(): GradleBuildProject.PluginType =
+ GradleBuildProject.PluginType.FUSED_LIBRARIES
+
+ override fun apply(project: Project) {
+ super.basePluginApply(project)
+
+ // so far by default, we consume and publish only 'debug' variant
+
+ // 'include' is the configuration that users will use to indicate which dependencies should
+ // be fused.
+ val includeConfigurations = project.configurations.create("include").also {
+ it.isCanBeConsumed = false
+ val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+ }
+ // This is the internal configuration that will be used to feed tasks that require access
+ // to the resolved 'include' dependency. It is for JAVA_API usage which mean all transitive
+ // dependencies that are implementation() scoped will not be included.
+ val includeApiClasspath = project.configurations.create("includeApiClasspath").also {
+ it.isCanBeConsumed = false
+ it.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_API)
+ )
+ val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+ it.extendsFrom(includeConfigurations)
+ }
+ // This is the configuration that will contain all the JAVA_API dependencies that are not
+ // fused in the resulting aar library.
+ val includedApiUnmerged = project.configurations.create("includeApiUnmerged").also {
+ it.isCanBeConsumed = true
+ it.isCanBeResolved = true
+ it.incoming.beforeResolve(
+ SegregatingConstraintHandler(
+ includeApiClasspath,
+ it,
+ variantScope.mergeSpec,
+ project,
+ )
+ )
+ }
+ // This is the internal configuration that will be used to feed tasks that require access
+ // to the resolved 'include' dependency. It is for JAVA_RUNTIME usage which mean all transitive
+ // dependencies that are implementation() scoped will be included.
+ val includeRuntimeClasspath =
+ project.configurations.create("includeRuntimeClasspath").also {
+ it.isCanBeConsumed = false
+ it.isCanBeResolved = true
+
+ it.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
+ )
+ val buildType: BuildTypeAttr =
+ project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+
+ it.extendsFrom(includeConfigurations)
+ }
+ // This is the configuration that will contain all the JAVA_RUNTIME dependencies that are
+ // not fused in the resulting aar library.
+ val includeRuntimeUnmerged = project.configurations.create("includeRuntimeUnmerged").also {
+ it.isCanBeConsumed = false
+ it.isCanBeResolved = true
+ it.incoming.beforeResolve(
+ SegregatingConstraintHandler(
+ includeConfigurations,
+ it,
+ variantScope.mergeSpec,
+ project,
+ )
+ )
+ }
+ // this is the outgoing configuration for JAVA_API scoped declarations, it will contain
+ // this module and all transitive non merged dependencies
+ fun configureElements(
+ elements: Configuration,
+ usage: String,
+ artifacts: ArtifactsImpl,
+ publicationArtifact: Artifact.Single<RegularFile>,
+ publicationArtifactType: AndroidArtifacts.ArtifactType
+ ) {
+ // we are only interested in the last provider in the chain of transformers for this bundle.
+ // Obviously, this is theoretical at this point since there is no variant API to replace
+ // artifacts, there is always only one.
+ val bundleTaskProvider = publicationArtifact.let {
+ artifacts
+ .getArtifactContainer(it)
+ .getTaskProviders()
+ .last()
+ }
+ elements.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, usage)
+ )
+ elements.isCanBeResolved = false
+ elements.isCanBeConsumed = true
+ elements.isTransitive = true
+
+ elements.outgoing.variants { variants ->
+ variants.create(publicationArtifactType.type) { variant ->
+ variant.artifact(bundleTaskProvider) { artifact ->
+ artifact.type = publicationArtifactType.type
+ }
+ }
+ }
+ }
- override val artifactForPublication: Artifact.Single<RegularFile>
- get() = FusedLibraryInternalArtifactType.BUNDLED_LIBRARY
+ val includeApiElements =
+ project.configurations.create("apiElements") { apiElements ->
+ configureElements(
+ apiElements,
+ Usage.JAVA_API,
+ variantScope.artifacts,
+ FusedLibraryInternalArtifactType.BUNDLED_LIBRARY,
+ AndroidArtifacts.ArtifactType.AAR)
- override val artifactTypeForPublication: AndroidArtifacts.ArtifactType
- get() = AndroidArtifacts.ArtifactType.AAR
+ apiElements.extendsFrom(includedApiUnmerged)
+ }
+ // this is the outgoing configuration for JAVA_RUNTIME scoped declarations, it will contain
+ // this module and all transitive non merged dependencies
+ val includeRuntimeElements =
+ project.configurations.create("runtimeElements") { runtimeElements ->
+ configureElements(
+ runtimeElements,
+ Usage.JAVA_RUNTIME,
+ variantScope.artifacts,
+ FusedLibraryInternalArtifactType.BUNDLED_LIBRARY,
+ AndroidArtifacts.ArtifactType.AAR)
+ runtimeElements.extendsFrom(includeRuntimeUnmerged)
+ }
+
+ val configurationsToAdd = listOf(includeApiClasspath, includeRuntimeClasspath)
+ configurationsToAdd.forEach { configuration ->
+ variantScope.incomingConfigurations.addConfiguration(configuration)
+ }
+ maybePublishToMaven(
+ project,
+ includeApiElements,
+ includeRuntimeElements,
+ includeRuntimeUnmerged
+ )
+ }
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt
index 762746fb79..07bab17956 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/plugins/PrivacySandboxSdkPlugin.kt
@@ -17,9 +17,15 @@
package com.android.build.gradle.internal.plugins
import com.android.build.api.artifact.Artifact
+import com.android.build.api.artifact.impl.ArtifactsImpl
+import com.android.build.api.attributes.BuildTypeAttr
import com.android.build.api.dsl.PrivacySandboxSdkExtension
import com.android.build.gradle.internal.dsl.InternalPrivacySandboxSdkExtension
import com.android.build.gradle.internal.dsl.PrivacySandboxSdkExtensionImpl
+import com.android.build.gradle.internal.fusedlibrary.SegregatingConstraintHandler
+import com.android.build.gradle.internal.fusedlibrary.configureTransforms
+import com.android.build.gradle.internal.fusedlibrary.createTasks
+import com.android.build.gradle.internal.fusedlibrary.getDslServices
import com.android.build.gradle.internal.privaysandboxsdk.PrivacySandboxSdkInternalArtifactType
import com.android.build.gradle.internal.privaysandboxsdk.PrivacySandboxSdkVariantScope
import com.android.build.gradle.internal.privaysandboxsdk.PrivacySandboxSdkVariantScopeImpl
@@ -27,6 +33,7 @@ import com.android.build.gradle.internal.publishing.AndroidArtifacts
import com.android.build.gradle.internal.res.PrivacySandboxSdkLinkAndroidResourcesTask
import com.android.build.gradle.internal.services.Aapt2DaemonBuildService
import com.android.build.gradle.internal.services.Aapt2ThreadPoolBuildService
+import com.android.build.gradle.internal.services.DslServices
import com.android.build.gradle.internal.services.TaskCreationServicesImpl
import com.android.build.gradle.internal.services.VersionedSdkLoaderService
import com.android.build.gradle.internal.tasks.AppMetadataTask
@@ -47,99 +54,250 @@ import com.android.build.gradle.tasks.PrivacySandboxSdkMergeResourcesTask
import com.android.repository.Revision
import com.google.wireless.android.sdk.stats.GradleBuildProject
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.attributes.Usage
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.file.RegularFile
import org.gradle.build.event.BuildEventsListenerRegistry
import javax.inject.Inject
class PrivacySandboxSdkPlugin @Inject constructor(
- listenerRegistry: BuildEventsListenerRegistry,
-): AbstractPrivacySandboxPlugin(listenerRegistry) {
+ val softwareComponentFactory: SoftwareComponentFactory,
+ listenerRegistry: BuildEventsListenerRegistry,
+) : AndroidPluginBaseServices(listenerRegistry), Plugin<Project> {
- private val versionedSdkLoaderService: VersionedSdkLoaderService by lazy {
+ val dslServices: DslServices by lazy(LazyThreadSafetyMode.NONE) {
+ withProject("dslServices") { project ->
+ getDslServices(project, projectServices)
+ }
+ }
+
+ private val versionedSdkLoaderService: VersionedSdkLoaderService by lazy(LazyThreadSafetyMode.NONE) {
withProject("versionedSdkLoaderService") { project ->
VersionedSdkLoaderService(
- dslServices,
- project,
- {
- variantScope.compileSdkVersion
- },
- {
- Revision.parseRevision(extension.buildToolsVersion, Revision.Precision.MICRO)
- },
+ dslServices,
+ project,
+ { variantScope.compileSdkVersion },
+ {
+ Revision.parseRevision(extension.buildToolsVersion,
+ Revision.Precision.MICRO)
+ },
)
}
}
// so far, there is only one variant.
- override val variantScope: PrivacySandboxSdkVariantScope by lazy {
+ private val variantScope: PrivacySandboxSdkVariantScope by lazy {
withProject("variantScope") { project ->
PrivacySandboxSdkVariantScopeImpl(
- project,
- TaskCreationServicesImpl(projectServices),
- { extension },
- {
- BootClasspathConfigImpl(
+ project,
+ TaskCreationServicesImpl(projectServices),
+ { extension },
+ ) {
+ BootClasspathConfigImpl(
project,
projectServices,
versionedSdkLoaderService,
null,
false
- )
- }
- )
+ )
+ }
}
}
- private val extension: PrivacySandboxSdkExtension by lazy {
+ private val extension: PrivacySandboxSdkExtension by lazy(LazyThreadSafetyMode.NONE)
+ {
withProject("extension") { project ->
instantiateExtension(project)
}
}
+ override fun configureProject(project: Project) {
+ val projectOptions = projectServices.projectOptions
+ Aapt2ThreadPoolBuildService.RegistrationAction(project, projectOptions).execute()
+ Aapt2DaemonBuildService.RegistrationAction(project, projectOptions).execute()
+ }
+
override fun configureExtension(project: Project) {
extension
}
override fun apply(project: Project) {
- super.apply(project)
+ super.basePluginApply(project)
if (!projectServices.projectOptions[BooleanOption.PRIVACY_SANDBOX_SDK_SUPPORT]) {
throw GradleException(
"Privacy Sandbox SDK support is experimental, and must be explicitly enabled.\n" +
- "To enable support, add\n" +
- " ${BooleanOption.PRIVACY_SANDBOX_SDK_SUPPORT.propertyName}=true\n" +
- "to your project's gradle.properties file."
+ "To enable support, add\n" +
+ " ${BooleanOption.PRIVACY_SANDBOX_SDK_SUPPORT.propertyName}=true\n" +
+ "to your project's gradle.properties file."
+ )
+ }
+
+ // so far by default, we consume and publish only 'debug' variant
+
+ // 'include' is the configuration that users will use to indicate which dependencies should
+ // be fused.
+ val includeConfigurations = project.configurations.create("include").also {
+ it.isCanBeConsumed = false
+ val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+ }
+ // This is the internal configuration that will be used to feed tasks that require access
+ // to the resolved 'include' dependency. It is for JAVA_API usage which mean all transitive
+ // dependencies that are implementation() scoped will not be included.
+ val includeApiClasspath = project.configurations.create("includeApiClasspath").also {
+ it.isCanBeConsumed = false
+ it.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_API)
+ )
+ val buildType: BuildTypeAttr = project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+ it.extendsFrom(includeConfigurations)
+ }
+ // This is the configuration that will contain all the JAVA_API dependencies that are not
+ // fused in the resulting aar library.
+ val includedApiUnmerged = project.configurations.create("includeApiUnmerged").also {
+ it.isCanBeConsumed = true
+ it.isCanBeResolved = true
+ it.incoming.beforeResolve(
+ SegregatingConstraintHandler(
+ includeApiClasspath,
+ it,
+ variantScope.mergeSpec,
+ project,
+ )
+ )
+ }
+ // This is the internal configuration that will be used to feed tasks that require access
+ // to the resolved 'include' dependency. It is for JAVA_RUNTIME usage which mean all transitive
+ // dependencies that are implementation() scoped will be included.
+ val includeRuntimeClasspath =
+ project.configurations.create("includeRuntimeClasspath").also {
+ it.isCanBeConsumed = false
+ it.isCanBeResolved = true
+
+ it.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)
+ )
+ val buildType: BuildTypeAttr =
+ project.objects.named(BuildTypeAttr::class.java, "debug")
+ it.attributes.attribute(
+ BuildTypeAttr.ATTRIBUTE,
+ buildType,
+ )
+
+ it.extendsFrom(includeConfigurations)
+ }
+ // This is the configuration that will contain all the JAVA_RUNTIME dependencies that are
+ // not fused in the resulting aar library.
+ val includeRuntimeUnmerged = project.configurations.create("includeRuntimeUnmerged").also {
+ it.isCanBeConsumed = false
+ it.isCanBeResolved = true
+ it.incoming.beforeResolve(
+ SegregatingConstraintHandler(
+ includeConfigurations,
+ it,
+ variantScope.mergeSpec,
+ project,
+ )
+ )
+ }
+ // this is the outgoing configuration for JAVA_API scoped declarations, it will contain
+ // this module and all transitive non merged dependencies
+ fun configureElements(
+ elements: Configuration,
+ usage: String,
+ artifacts: ArtifactsImpl,
+ publicationArtifact: Artifact.Single<RegularFile>,
+ publicationArtifactType: AndroidArtifacts.ArtifactType
+ ) {
+ // we are only interested in the last provider in the chain of transformers for this bundle.
+ // Obviously, this is theoretical at this point since there is no variant API to replace
+ // artifacts, there is always only one.
+ val bundleTaskProvider = publicationArtifact.let {
+ artifacts
+ .getArtifactContainer(it)
+ .getTaskProviders()
+ .last()
+ }
+ elements.attributes.attribute(
+ Usage.USAGE_ATTRIBUTE,
+ project.objects.named(Usage::class.java, usage)
)
+ elements.isCanBeResolved = false
+ elements.isCanBeConsumed = true
+ elements.isTransitive = true
+
+ elements.outgoing.variants { variants ->
+ variants.create(publicationArtifactType.type) { variant ->
+ variant.artifact(bundleTaskProvider) { artifact ->
+ artifact.type = publicationArtifactType.type
+ }
+ }
+ }
+ }
+ project.configurations.create("apiElements") { apiElements ->
+ configureElements(
+ apiElements,
+ Usage.JAVA_API,
+ variantScope.artifacts,
+ PrivacySandboxSdkInternalArtifactType.ASAR,
+ AndroidArtifacts.ArtifactType.ANDROID_PRIVACY_SANDBOX_SDK_ARCHIVE)
+
+ apiElements.extendsFrom(includedApiUnmerged)
+ }
+ // this is the outgoing configuration for JAVA_RUNTIME scoped declarations, it will contain
+ // this module and all transitive non merged dependencies
+ project.configurations.create("runtimeElements") { runtimeElements ->
+ configureElements(
+ runtimeElements,
+ Usage.JAVA_RUNTIME,
+ variantScope.artifacts,
+ PrivacySandboxSdkInternalArtifactType.ASAR,
+ AndroidArtifacts.ArtifactType.ANDROID_PRIVACY_SANDBOX_SDK_ARCHIVE)
+ runtimeElements.extendsFrom(includeRuntimeUnmerged)
+ }
+ val configurationsToAdd = listOf(includeApiClasspath, includeRuntimeClasspath)
+ configurationsToAdd.forEach { configuration ->
+ variantScope.incomingConfigurations.addConfiguration(configuration)
}
- Aapt2ThreadPoolBuildService.RegistrationAction(project, projectServices.projectOptions).execute()
- Aapt2DaemonBuildService.RegistrationAction(project, projectServices.projectOptions).execute()
}
private fun instantiateExtension(project: Project): PrivacySandboxSdkExtension {
- val sdkLibraryExtensionImpl= dslServices.newDecoratedInstance(
- PrivacySandboxSdkExtensionImpl::class.java,
- dslServices,
+ val sdkLibraryExtensionImpl = dslServices.newDecoratedInstance(
+ PrivacySandboxSdkExtensionImpl::class.java,
+ dslServices,
)
abstract class Extension(
- val publicExtensionImpl: PrivacySandboxSdkExtensionImpl,
+ val publicExtensionImpl: PrivacySandboxSdkExtensionImpl,
): InternalPrivacySandboxSdkExtension by publicExtensionImpl
return project.extensions.create(
- PrivacySandboxSdkExtension::class.java,
- "android",
- Extension::class.java,
- sdkLibraryExtensionImpl
+ PrivacySandboxSdkExtension::class.java,
+ "android",
+ Extension::class.java,
+ sdkLibraryExtensionImpl
)
}
override fun createTasks(project: Project) {
+ configureTransforms(project, projectServices)
createTasks(
project,
- variantScope,
+ variantScope.artifacts,
+ PrivacySandboxSdkInternalArtifactType.ASAR,
listOf(
AppMetadataTask.PrivacySandboxSdkCreationAction(variantScope),
FusedLibraryMergeClasses.PrivacySandboxSdkCreationAction(variantScope),
@@ -154,18 +312,10 @@ class PrivacySandboxSdkPlugin @Inject constructor(
PerModuleBundleTask.PrivacySandboxSdkCreationAction(variantScope),
PackagePrivacySandboxSdkBundle.CreationAction(variantScope),
ValidateSigningTask.PrivacySandboxSdkCreationAction(variantScope),
- ) + FusedLibraryMergeArtifactTask.getCreationActions(variantScope),
+ ) + FusedLibraryMergeArtifactTask.getCreationActions(variantScope)
)
}
- override fun getAnalyticsPluginType(): GradleBuildProject.PluginType =
- GradleBuildProject.PluginType.PRIVACY_SANDBOX_SDK
-
- /**
- * ASB only get published to Play Store, not maven
- */
- override val artifactForPublication: Artifact.Single<RegularFile> = PrivacySandboxSdkInternalArtifactType.ASAR
-
- override val artifactTypeForPublication: AndroidArtifacts.ArtifactType
- get() = AndroidArtifacts.ArtifactType.ANDROID_PRIVACY_SANDBOX_SDK_ARCHIVE
+ override fun getAnalyticsPluginType(): GradleBuildProject.PluginType =
+ GradleBuildProject.PluginType.PRIVACY_SANDBOX_SDK
}