blob: d7ccdc4315b0b73b1bccc63cdd2e4bc09bf1d93e [file] [log] [blame]
/*
* 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.tasks
import com.android.SdkConstants
import com.android.SdkConstants.FN_ANDROID_MANIFEST_XML
import com.android.build.gradle.internal.LoggerWrapper
import com.android.build.gradle.internal.fusedlibrary.FusedLibraryInternalArtifactType
import com.android.build.gradle.internal.fusedlibrary.FusedLibraryVariantScope
import com.android.build.gradle.internal.profile.ProfileAwareWorkAction
import com.android.build.gradle.internal.publishing.AndroidArtifacts
import com.android.build.gradle.internal.services.getBuildService
import com.android.build.gradle.internal.tasks.configureVariantProperties
import com.android.build.gradle.internal.tasks.factory.TaskCreationAction
import com.android.build.gradle.internal.tasks.manifest.ManifestProviderImpl
import com.android.build.gradle.internal.tasks.manifest.mergeManifests
import com.android.build.gradle.internal.utils.setDisallowChanges
import com.android.build.gradle.tasks.ProcessApplicationManifest.Companion.getArtifactName
import com.android.manifmerger.ManifestMerger2
import com.android.utils.FileUtils
import org.gradle.api.artifacts.ArtifactCollection
import org.gradle.api.attributes.Usage
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskProvider
import java.io.File
/**
* Merges Manifests from libraries that will be included with in fused library.
*/
@CacheableTask
abstract class FusedLibraryManifestMergerTask : ManifestProcessorTask() {
@get:Internal
abstract val libraryManifests: Property<ArtifactCollection>
@get:OutputFile
abstract val mergedFusedLibraryManifest: RegularFileProperty
@get:Input
abstract val namespace: Property<String>
@get:Input
abstract val minSdk: Property<Int>
@get:Internal
abstract val tmpDir: DirectoryProperty
/* For adding a dependency on the files used in identifierToManifestDependencyFile. */
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val libraryManifestFiles: FileCollection
get() = libraryManifests.get().artifactFiles
override fun doTaskAction() {
FileUtils.cleanOutputDir(tmpDir.get().asFile)
workerExecutor.noIsolation().submit(FusedLibraryManifestMergerWorkAction::class.java) {
configureParameters(it)
it.mainAndroidManifest.set(
createTempLibraryManifest(
tmpDir.get().asFile,
namespace.get()
)
)
}
}
protected fun configureParameters(parameters: FusedLibraryManifestMergerParams) {
parameters.initializeFromAndroidVariantTask(this)
val identifierToManifestDependencyFile = libraryManifests.get().associate { getArtifactName(it) to it.file }
parameters.dependencies.set(identifierToManifestDependencyFile)
parameters.namespace.set(namespace)
parameters.minSdk.set(minSdk)
parameters.outMergedManifestLocation.set(mergedFusedLibraryManifest)
parameters.reportFile.set(reportFile)
}
abstract class FusedLibraryManifestMergerParams: ProfileAwareWorkAction.Parameters() {
abstract val mainAndroidManifest: RegularFileProperty
abstract val dependencies: MapProperty<String, File>
abstract val namespace: Property<String>
abstract val minSdk: Property<Int>
abstract val outMergedManifestLocation: RegularFileProperty
abstract val reportFile: RegularFileProperty
}
abstract class FusedLibraryManifestMergerWorkAction
: ProfileAwareWorkAction<FusedLibraryManifestMergerParams>() {
override fun run() {
with(parameters!!) {
val dependencyManifests =
dependencies.get().map { ManifestProviderImpl(it.value, it.key) }
mergeManifests(
mainManifest = mainAndroidManifest.get().asFile,
manifestOverlays = emptyList(),
dependencies = dependencyManifests,
navigationJsons = emptyList(),
featureName = null,
packageOverride = namespace.get(),
namespace = namespace.get(),
profileable = false,
versionCode = null,
versionName = null,
minSdkVersion = minSdk.get().toString(),
targetSdkVersion = null,
maxSdkVersion = null,
testOnly = false,
outMergedManifestLocation = outMergedManifestLocation.get().asFile.absolutePath,
outAaptSafeManifestLocation = null,
mergeType = ManifestMerger2.MergeType.FUSED_LIBRARY,
placeHolders = emptyMap(),
optionalFeatures = listOf(ManifestMerger2.Invoker.Feature.NO_PLACEHOLDER_REPLACEMENT),
dependencyFeatureNames = emptyList(),
reportFile = reportFile.get().asFile,
logger = LoggerWrapper.getLogger(FusedLibraryManifestMergerTask::class.java))
}
}
}
abstract class AbstractCreationAction<T : FusedLibraryManifestMergerTask>(open val creationConfig: FusedLibraryVariantScope) :
TaskCreationAction<T>() {
override val name: String
get() = "mergeManifest"
override fun handleProvider(taskProvider: TaskProvider<T>) {
super.handleProvider(taskProvider)
creationConfig.artifacts.setInitialProvider(
taskProvider,
FusedLibraryManifestMergerTask::mergedFusedLibraryManifest
).withName(FN_ANDROID_MANIFEST_XML)
.on(FusedLibraryInternalArtifactType.MERGED_MANIFEST)
creationConfig.artifacts.setInitialProvider(
taskProvider,
FusedLibraryManifestMergerTask::reportFile
).atLocation(
FileUtils.join(
creationConfig.layout.projectDirectory.asFile,
"build",
SdkConstants.FD_OUTPUTS,
SdkConstants.FD_LOGS
).absolutePath
).withName("manifest-merger-$name-report.txt")
.on(FusedLibraryInternalArtifactType.MANIFEST_MERGE_REPORT)
SdkConstants.FD_OUTPUT
}
override fun configure(task: T) {
task.configureVariantProperties("", task.project.gradle.sharedServices)
val libraryManifests = creationConfig.dependencies.getArtifactCollection(
Usage.JAVA_RUNTIME,
creationConfig.mergeSpec,
AndroidArtifacts.ArtifactType.MANIFEST
)
task.libraryManifests.set(libraryManifests)
task.minSdk.setDisallowChanges(creationConfig.extension.minSdk)
task.namespace.set(creationConfig.extension.namespace)
task.tmpDir.setDisallowChanges(
creationConfig.layout.buildDirectory.dir("tmp/FusedLibraryManifestMerger")
)
}
}
class CreationAction(creationConfig: FusedLibraryVariantScope):
AbstractCreationAction<FusedLibraryManifestMergerTask>(creationConfig) {
override val type: Class<FusedLibraryManifestMergerTask>
get() = FusedLibraryManifestMergerTask::class.java
}
}