blob: a781a475a2325cf348efb6319020d3707815dcf7 [file] [log] [blame]
/*
* Copyright (C) 2015 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;
import static com.android.build.gradle.internal.cxx.configure.CxxCreateGradleTasksKt.createCxxVariantBuildTask;
import com.android.annotations.NonNull;
import com.android.build.api.transform.QualifiedContent.ScopeType;
import com.android.build.api.variant.VariantBuilder;
import com.android.build.gradle.BaseExtension;
import com.android.build.gradle.internal.component.ApkCreationConfig;
import com.android.build.gradle.internal.component.ApplicationCreationConfig;
import com.android.build.gradle.internal.component.ComponentCreationConfig;
import com.android.build.gradle.internal.component.TestComponentCreationConfig;
import com.android.build.gradle.internal.component.TestFixturesCreationConfig;
import com.android.build.gradle.internal.component.VariantCreationConfig;
import com.android.build.gradle.internal.feature.BundleAllClasses;
import com.android.build.gradle.internal.pipeline.TransformManager;
import com.android.build.gradle.internal.publishing.AndroidArtifacts;
import com.android.build.gradle.internal.tasks.AnalyticsRecordingTask;
import com.android.build.gradle.internal.tasks.ApkZipPackagingTask;
import com.android.build.gradle.internal.tasks.AppClasspathCheckTask;
import com.android.build.gradle.internal.tasks.AppPreBuildTask;
import com.android.build.gradle.internal.tasks.ApplicationIdWriterTask;
import com.android.build.gradle.internal.tasks.CheckManifest;
import com.android.build.gradle.internal.tasks.CheckMultiApkLibrariesTask;
import com.android.build.gradle.internal.tasks.CompressAssetsTask;
import com.android.build.gradle.internal.tasks.ExtractNativeDebugMetadataTask;
import com.android.build.gradle.internal.tasks.ExtractProfilerNativeDependenciesTask;
import com.android.build.gradle.internal.tasks.ModuleMetadataWriterTask;
import com.android.build.gradle.internal.tasks.StripDebugSymbolsTask;
import com.android.build.gradle.internal.tasks.TestPreBuildTask;
import com.android.build.gradle.internal.tasks.factory.GlobalTaskCreationConfig;
import com.android.build.gradle.internal.tasks.factory.TaskFactoryUtils;
import com.android.build.gradle.internal.tasks.factory.TaskManagerConfig;
import com.android.build.gradle.internal.tasks.featuresplit.PackagedDependenciesWriterTask;
import com.android.build.gradle.internal.variant.ComponentInfo;
import com.android.build.gradle.options.BooleanOption;
import com.android.build.gradle.options.ProjectOptions;
import com.android.build.gradle.tasks.ExtractDeepLinksTask;
import com.android.build.gradle.tasks.MergeResources;
import com.android.builder.core.ComponentType;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Set;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.resources.TextResourceFactory;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.compile.JavaCompile;
/** TaskManager for creating tasks in an Android application project. */
public abstract class AbstractAppTaskManager<
VariantBuilderT extends VariantBuilder, VariantT extends VariantCreationConfig>
extends TaskManager<VariantBuilderT, VariantT> {
protected AbstractAppTaskManager(
@NonNull Project project,
@NonNull Collection<? extends ComponentInfo<VariantBuilderT, VariantT>> variants,
@NonNull Collection<? extends TestComponentCreationConfig> testComponents,
@NonNull Collection<? extends TestFixturesCreationConfig> testFixturesComponents,
@NonNull GlobalTaskCreationConfig globalConfig,
@NonNull TaskManagerConfig localConfig,
@NonNull BaseExtension extension) {
super(
project,
variants,
testComponents,
testFixturesComponents,
globalConfig,
localConfig,
extension);
}
protected void createCommonTasks(@NonNull ComponentInfo<VariantBuilderT, VariantT> variant) {
ApkCreationConfig creationConfig = (ApkCreationConfig) variant.getVariant();
createAnchorTasks(creationConfig);
taskFactory.register(new ExtractDeepLinksTask.CreationAction(creationConfig));
// Create all current streams (dependencies mostly at this point)
createDependencyStreams(creationConfig);
// Add a task to publish the applicationId.
// TODO remove case once TaskManager's type param is based on BaseCreationConfig
createApplicationIdWriterTask(creationConfig);
// Add a task to check the manifest
taskFactory.register(new CheckManifest.CreationAction(creationConfig));
// Add a task to process the manifest(s)
createMergeApkManifestsTask(creationConfig);
// Add a task to create the res values
createGenerateResValuesTask(creationConfig);
// Add a task to compile renderscript files.
createRenderscriptTask(creationConfig);
// Add a task to merge the resource folders
createMergeResourcesTasks(creationConfig);
// Add tasks to compile shader
createShaderTask(creationConfig);
// Add a task to merge the asset folders
createMergeAssetsTask(creationConfig);
taskFactory.register(new CompressAssetsTask.CreationAction(creationConfig));
// Add a task to create the BuildConfig class
createBuildConfigTask(creationConfig);
// Add a task to process the Android Resources and generate source files
createApkProcessResTask(creationConfig);
// Add a task to process the java resources
createProcessJavaResTask(creationConfig);
createAidlTask(creationConfig);
maybeExtractProfilerDependencies(creationConfig);
// Set up the C/C++ external native build task
createCxxVariantBuildTask(
taskFactory, variant.getVariant(), project.getProviders(), project.getLayout());
// Add a task to merge the jni libs folders
createMergeJniLibFoldersTasks(creationConfig);
// Add data binding tasks if enabled
createDataBindingTasksIfNecessary(creationConfig);
// Add a task to auto-generate classes for ML model files.
createMlkitTask(creationConfig);
// Add a compile task
createCompileTask(creationConfig);
taskFactory.register(new StripDebugSymbolsTask.CreationAction(variant.getVariant()));
taskFactory.register(
new ExtractNativeDebugMetadataTask.FullCreationAction(variant.getVariant()));
taskFactory.register(
new ExtractNativeDebugMetadataTask.SymbolTableCreationAction(variant.getVariant()));
createPackagingTask(creationConfig);
taskFactory.register(new PackagedDependenciesWriterTask.CreationAction(creationConfig));
taskFactory.register(new ApkZipPackagingTask.CreationAction(creationConfig));
}
private void createCompileTask(@NonNull ApkCreationConfig creationConfig) {
TaskProvider<? extends JavaCompile> javacTask = createJavacTask(creationConfig);
addJavacClassesStream(creationConfig);
setJavaCompilerTask(javacTask, creationConfig);
createPostCompilationTasks(creationConfig);
}
@Override
protected void postJavacCreation(@NonNull ComponentCreationConfig creationConfig) {
super.postJavacCreation(creationConfig);
taskFactory.register(
new BundleAllClasses.CreationAction(
creationConfig, AndroidArtifacts.PublishedConfigType.API_ELEMENTS));
taskFactory.register(
new BundleAllClasses.CreationAction(
creationConfig, AndroidArtifacts.PublishedConfigType.RUNTIME_ELEMENTS));
}
@Override
protected void createVariantPreBuildTask(@NonNull ComponentCreationConfig creationConfig) {
final ComponentType componentType = creationConfig.getComponentType();
if (componentType.isApk()) {
boolean useDependencyConstraints =
creationConfig
.getServices()
.getProjectOptions()
.get(BooleanOption.USE_DEPENDENCY_CONSTRAINTS);
TaskProvider<? extends Task> task;
if (componentType.isTestComponent()) {
task =
taskFactory.register(
new TestPreBuildTask.CreationAction(
(TestComponentCreationConfig) creationConfig));
if (useDependencyConstraints) {
task.configure(t -> t.setEnabled(false));
}
} else {
task = taskFactory.register(AppPreBuildTask.getCreationAction(creationConfig));
ApkCreationConfig config = (ApkCreationConfig) creationConfig;
// Only record application ids for release artifacts
boolean analyticsEnabled =
creationConfig.getServices().getProjectOptions().isAnalyticsEnabled();
if (!config.getDebuggable() && analyticsEnabled) {
TaskProvider<AnalyticsRecordingTask> recordTask =
taskFactory.register(new AnalyticsRecordingTask.CreationAction(config));
task.configure(it -> it.finalizedBy(recordTask));
}
}
if (!useDependencyConstraints) {
TaskProvider<AppClasspathCheckTask> classpathCheck =
taskFactory.register(
new AppClasspathCheckTask.CreationAction(creationConfig));
TaskFactoryUtils.dependsOn(task, classpathCheck);
}
if (componentType.isBaseModule() && globalConfig.getHasDynamicFeatures()) {
TaskProvider<CheckMultiApkLibrariesTask> checkMultiApkLibrariesTask =
taskFactory.register(
new CheckMultiApkLibrariesTask.CreationAction(creationConfig));
TaskFactoryUtils.dependsOn(task, checkMultiApkLibrariesTask);
}
return;
}
super.createVariantPreBuildTask(creationConfig);
}
@NonNull
@Override
protected Set<ScopeType> getJavaResMergingScopes(
@NonNull ComponentCreationConfig creationConfig) {
return TransformManager.SCOPE_FULL_PROJECT;
}
private void createApplicationIdWriterTask(@NonNull ApkCreationConfig creationConfig) {
if (creationConfig.getComponentType().isBaseModule()) {
taskFactory.register(
new ModuleMetadataWriterTask.CreationAction(
(ApplicationCreationConfig) creationConfig));
}
// TODO b/141650037 - Only the base App should create this task once we get rid of
// getApplicationIdTextResource()
// Once this is removed, this whole methods can be moved to AppTaskManager
TaskProvider<? extends Task> applicationIdWriterTask =
taskFactory.register(new ApplicationIdWriterTask.CreationAction(creationConfig));
TextResourceFactory resources = project.getResources().getText();
// this builds the dependencies from the task, and its output is the textResource.
creationConfig.getOldVariantApiLegacySupport().getVariantData().applicationIdTextResource =
resources.fromFile(applicationIdWriterTask);
}
private void createMergeResourcesTasks(@NonNull ApkCreationConfig creationConfig) {
// The "big merge" of all resources, will merge and compile resources that will later
// be used for linking.
createMergeResourcesTask(
creationConfig,
true,
Sets.immutableEnumSet(MergeResources.Flag.PROCESS_VECTOR_DRAWABLES));
ProjectOptions projectOptions = creationConfig.getServices().getProjectOptions();
boolean nonTransitiveR = projectOptions.get(BooleanOption.NON_TRANSITIVE_R_CLASS);
boolean namespaced = creationConfig.getGlobal().getNamespacedAndroidResources();
// TODO(b/138780301): Also use compile time R class in android tests.
if ((projectOptions.get(BooleanOption.ENABLE_APP_COMPILE_TIME_R_CLASS) || nonTransitiveR)
&& !creationConfig.getComponentType().isForTesting()
&& !namespaced) {
// The "small merge" of only the app's local resources (can be multiple source-sets, but
// most of the time it's just one). This is used by the Process for generating the local
// R-def.txt file containing a list of resources defined in this module.
basicCreateMergeResourcesTask(
creationConfig,
MergeType.PACKAGE,
false,
false,
false,
ImmutableSet.of(),
null);
}
}
/** Extract dependencies for profiler supports if needed. */
private void maybeExtractProfilerDependencies(@NonNull ApkCreationConfig apkCreationConfig) {
if (apkCreationConfig.getShouldPackageProfilerDependencies()) {
taskFactory.register(
new ExtractProfilerNativeDependenciesTask.CreationAction(apkCreationConfig));
}
}
}