blob: ededadad86a462e44b45c1cf63e1b2f75a77bf65 [file] [log] [blame]
/*
* Copyright (C) 2017 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.build.gradle.internal.scope.BuildArtifactsHolder
import com.android.build.gradle.internal.scope.BuildElements
import com.android.build.gradle.internal.scope.BuildElementsCopyParams
import com.android.build.gradle.internal.scope.BuildElementsCopyRunnable
import com.android.build.gradle.internal.scope.BuildOutput
import com.android.build.gradle.internal.scope.ExistingBuildElements
import com.android.build.gradle.internal.scope.InternalArtifactType
import com.android.build.gradle.internal.scope.VariantScope
import com.android.build.gradle.internal.tasks.NonIncrementalTask
import com.android.build.gradle.internal.tasks.factory.VariantTaskCreationAction
import com.android.utils.FileUtils
import com.google.common.collect.ImmutableList
import org.gradle.api.file.Directory
import java.io.File
import java.util.ArrayList
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskProvider
/**
* Copy the location our various tasks outputs into a single location.
*
* <p>This is useful when having configuration or feature splits which are located in different
* folders since they are produced by different tasks.
*/
abstract class CopyOutputs : NonIncrementalTask() {
@get:OutputDirectory
abstract val destinationDir: DirectoryProperty
@get:InputFiles
abstract val fullApks: DirectoryProperty
@get:InputFiles
@get:Optional
abstract val abiSplits: DirectoryProperty
@get:InputFiles
@get:Optional
abstract val resourcesSplits: DirectoryProperty
// FIX ME : add incrementality
override fun doTaskAction() {
FileUtils.cleanOutputDir(destinationDir.get().asFile)
val buildElementsCallables = ArrayList<Callable<BuildElements>>()
buildElementsCallables.add(copy(InternalArtifactType.FULL_APK, fullApks))
buildElementsCallables.add(copy(InternalArtifactType.ABI_PACKAGED_SPLIT, abiSplits))
buildElementsCallables.add(
copy(
InternalArtifactType.DENSITY_OR_LANGUAGE_PACKAGED_SPLIT,
resourcesSplits
)
)
val buildOutputs = ImmutableList.builder<BuildOutput>()
for (buildElementsCallable in buildElementsCallables) {
try {
buildOutputs.addAll(buildElementsCallable.call())
} catch (e: Exception) {
throw ExecutionException(e)
}
}
BuildElements(buildOutputs.build()).save(destinationDir.get().asFile)
}
private fun copy(
inputType: InternalArtifactType,
inputs: DirectoryProperty
): Callable<BuildElements> {
return ExistingBuildElements.from(inputType, inputs)
.transform(
getWorkerFacadeWithWorkers(),
BuildElementsCopyRunnable::class.java
) { _, inputFile ->
BuildElementsCopyParams(
inputFile,
File(
destinationDir.get().asFile,
inputFile.name
)
)
}
.intoCallable(InternalArtifactType.APK)
}
class CreationAction(variantScope: VariantScope, private val destinationDir: File) :
VariantTaskCreationAction<CopyOutputs>(variantScope) {
override val name: String = variantScope.getTaskName("copyOutputs")
override val type: Class<CopyOutputs> = CopyOutputs::class.java
override fun handleProvider(taskProvider: TaskProvider<out CopyOutputs>) {
super.handleProvider(taskProvider)
variantScope
.artifacts
.producesDir(
InternalArtifactType.APK,
BuildArtifactsHolder.OperationType.INITIAL,
taskProvider,
CopyOutputs::destinationDir,
destinationDir.absolutePath,
""
)
}
override fun configure(task: CopyOutputs) {
super.configure(task)
val artifacts = variantScope.artifacts
artifacts.setTaskInputToFinalProduct<Directory>(
InternalArtifactType.FULL_APK,
task.fullApks
)
artifacts.setTaskInputToFinalProduct<Directory>(
InternalArtifactType.ABI_PACKAGED_SPLIT, task.abiSplits
)
artifacts.setTaskInputToFinalProduct<Directory>(
InternalArtifactType.DENSITY_OR_LANGUAGE_PACKAGED_SPLIT,
task.resourcesSplits
)
}
}
}