blob: 5bcc4f8bdd611cdc86a1d22b11f2bf90c6283cbd [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.scope;
import static com.android.build.gradle.internal.TaskManager.DIR_BUNDLES;
import static com.android.builder.model.AndroidProject.FD_GENERATED;
import static com.android.builder.model.AndroidProject.FD_OUTPUTS;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.internal.core.Abi;
import com.android.build.gradle.internal.core.GradleVariantConfiguration;
import com.android.build.gradle.internal.coverage.JacocoInstrumentTask;
import com.android.build.gradle.internal.tasks.CheckManifest;
import com.android.build.gradle.internal.tasks.FileSupplier;
import com.android.build.gradle.internal.tasks.MergeJavaResourcesTask;
import com.android.build.gradle.internal.tasks.PrepareDependenciesTask;
import com.android.build.gradle.internal.variant.ApkVariantData;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.android.build.gradle.internal.variant.LibraryVariantData;
import com.android.build.gradle.internal.variant.TestVariantData;
import com.android.build.gradle.tasks.AidlCompile;
import com.android.build.gradle.tasks.BinaryFileProviderTask;
import com.android.build.gradle.tasks.Dex;
import com.android.build.gradle.tasks.GenerateBuildConfig;
import com.android.build.gradle.tasks.GenerateResValues;
import com.android.build.gradle.tasks.JackTask;
import com.android.build.gradle.tasks.JavaResourcesProvider;
import com.android.build.gradle.tasks.MergeAssets;
import com.android.build.gradle.tasks.MergeResources;
import com.android.build.gradle.tasks.NdkCompile;
import com.android.build.gradle.tasks.ProcessAndroidResources;
import com.android.build.gradle.tasks.RenderscriptCompile;
import com.android.builder.core.VariantConfiguration;
import com.android.builder.core.VariantType;
import com.android.builder.signing.SignedJarBuilder;
import com.android.utils.FileUtils;
import com.android.utils.StringHelper;
import com.google.common.base.Objects;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Sync;
import org.gradle.api.tasks.compile.AbstractCompile;
import org.gradle.api.tasks.compile.JavaCompile;
import java.io.File;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* A scope containing data for a specific variant.
*/
public class VariantScope {
@NonNull
private GlobalScope globalScope;
@NonNull
private BaseVariantData<? extends BaseVariantOutputData> variantData;
@Nullable
private Collection<Object> ndkBuildable;
@Nullable
private Collection<File> ndkSoFolder;
@Nullable
private File ndkObjFolder;
@NonNull
private Map<Abi, File> ndkDebuggableLibraryFolders = Maps.newHashMap();
@Nullable
private File mergeResourceOutputDir;
// Tasks
private AndroidTask<Task> preBuildTask;
private AndroidTask<PrepareDependenciesTask> prepareDependenciesTask;
private AndroidTask<ProcessAndroidResources> generateRClassTask;
private AndroidTask<Task> sourceGenTask;
private AndroidTask<Task> resourceGenTask;
private AndroidTask<Task> assetGenTask;
private AndroidTask<CheckManifest> checkManifestTask;
private AndroidTask<RenderscriptCompile> renderscriptCompileTask;
private AndroidTask<AidlCompile> aidlCompileTask;
@Nullable
private AndroidTask<MergeResources> mergeResourcesTask;
@Nullable
private AndroidTask<MergeAssets> mergeAssetsTask;
private AndroidTask<GenerateBuildConfig> generateBuildConfigTask;
private AndroidTask<GenerateResValues> generateResValuesTask;
@Nullable
private AndroidTask<Dex> dexTask;
@Nullable
private AndroidTask jacocoIntrumentTask;
private AndroidTask<Sync> processJavaResourcesTask;
private AndroidTask<MergeJavaResourcesTask> mergeJavaResourcesTask;
private JavaResourcesProvider javaResourcesProvider;
private AndroidTask<NdkCompile> ndkCompileTask;
/** @see BaseVariantData#javaCompilerTask */
@Nullable
private AndroidTask<? extends AbstractCompile> javaCompilerTask;
@Nullable
private AndroidTask<JavaCompile> javacTask;
@Nullable
private AndroidTask<JackTask> jackTask;
// empty anchor compile task to set all compilations tasks as dependents.
private AndroidTask<Task> compileTask;
private AndroidTask<JacocoInstrumentTask> jacocoInstrumentTask;
private FileSupplier mappingFileProviderTask;
private AndroidTask<BinaryFileProviderTask> binayFileProviderTask;
// TODO : why is Jack not registered as the obfuscationTask ???
private AndroidTask<? extends Task> obfuscationTask;
private File resourceOutputDir;
public VariantScope(
@NonNull GlobalScope globalScope,
@NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
this.globalScope = globalScope;
this.variantData = variantData;
}
@NonNull
public GlobalScope getGlobalScope() {
return globalScope;
}
@NonNull
public BaseVariantData<? extends BaseVariantOutputData> getVariantData() {
return variantData;
}
@NonNull
public GradleVariantConfiguration getVariantConfiguration() {
return variantData.getVariantConfiguration();
}
@NonNull
public String getTaskName(@NonNull String prefix) {
return getTaskName(prefix, "");
}
@NonNull
public String getTaskName(@NonNull String prefix, @NonNull String suffix) {
return prefix + StringHelper.capitalize(getVariantConfiguration().getFullName()) + suffix;
}
@Nullable
public Collection<Object> getNdkBuildable() {
return ndkBuildable;
}
public void setNdkBuildable(@NonNull Collection<Object> ndkBuildable) {
this.ndkBuildable = ndkBuildable;
}
@Nullable
public Collection<File> getNdkSoFolder() {
return ndkSoFolder;
}
public void setNdkSoFolder(@NonNull Collection<File> ndkSoFolder) {
this.ndkSoFolder = ndkSoFolder;
}
@Nullable
public File getNdkObjFolder() {
return ndkObjFolder;
}
public void setNdkObjFolder(@NonNull File ndkObjFolder) {
this.ndkObjFolder = ndkObjFolder;
}
/**
* Return the folder containing the shared object with debugging symbol for the specified ABI.
*/
@Nullable
public File getNdkDebuggableLibraryFolders(@NonNull Abi abi) {
return ndkDebuggableLibraryFolders.get(abi);
}
public void addNdkDebuggableLibraryFolders(@NonNull Abi abi, @NonNull File searchPath) {
this.ndkDebuggableLibraryFolders.put(abi, searchPath);
}
@NonNull
public Set<File> getJniFolders() {
assert getNdkSoFolder() != null;
VariantConfiguration config = getVariantConfiguration();
ApkVariantData apkVariantData = (ApkVariantData) variantData;
// for now only the project's compilation output.
Set<File> set = Sets.newHashSet();
set.addAll(getNdkSoFolder());
set.add(getRenderscriptLibOutputDir());
set.addAll(config.getLibraryJniFolders());
set.addAll(config.getJniLibsList());
if (config.getMergedFlavor().getRenderscriptSupportModeEnabled() != null &&
config.getMergedFlavor().getRenderscriptSupportModeEnabled()) {
File rsLibs = globalScope.getAndroidBuilder().getSupportNativeLibFolder();
if (rsLibs != null && rsLibs.isDirectory()) {
set.add(rsLibs);
}
}
return set;
}
@Nullable
public BaseVariantData getTestedVariantData() {
return variantData instanceof TestVariantData ?
(BaseVariantData) ((TestVariantData) variantData).getTestedVariantData() :
null;
}
// Precomputed file paths.
@NonNull
public File getDexOutputFolder() {
return new File(globalScope.getIntermediatesDir(), "/dex/" + getVariantConfiguration().getDirName());
}
@NonNull
public FileCollection getJavaClasspath() {
return getGlobalScope().getProject().files(
getGlobalScope().getAndroidBuilder().getCompileClasspath(
getVariantData().getVariantConfiguration()));
}
@NonNull
public File getJavaOutputDir() {
return new File(globalScope.getIntermediatesDir(), "/classes/" +
variantData.getVariantConfiguration().getDirName());
}
@NonNull
public File getJavaDependencyCache() {
return new File(globalScope.getIntermediatesDir(), "/dependency-cache/" +
variantData.getVariantConfiguration().getDirName());
}
@NonNull
public File getPreDexOutputDir() {
return new File(globalScope.getIntermediatesDir(), "/pre-dexed/" +
getVariantConfiguration().getDirName());
}
@NonNull
public File getProguardOutputFile() {
return (variantData instanceof LibraryVariantData) ?
new File(globalScope.getIntermediatesDir(),
DIR_BUNDLES + "/" + getVariantConfiguration().getDirName()
+ "/classes.jar") :
new File(globalScope.getIntermediatesDir(),
"/classes-proguard/" + getVariantConfiguration().getDirName()
+ "/classes.jar");
}
@NonNull
public File getProguardComponentsJarFile() {
return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ "/componentClasses.jar");
}
@NonNull
public File getJarMergingOutputFile() {
return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ "/allclasses.jar");
}
@NonNull
public File getManifestKeepListFile() {
return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ "/manifest_keep.txt");
}
@NonNull
public File getMainDexListFile() {
return new File(globalScope.getIntermediatesDir(), "multi-dex/" + getVariantConfiguration().getDirName()
+ "/maindexlist.txt");
}
@NonNull
public File getRenderscriptSourceOutputDir() {
return new File(globalScope.getGeneratedDir(),
"source/rs/" + variantData.getVariantConfiguration().getDirName());
}
@NonNull
public File getRenderscriptLibOutputDir() {
return new File(globalScope.getGeneratedDir(),
"rs/" + variantData.getVariantConfiguration().getDirName() + "/lib");
}
@NonNull
public File getSymbolLocation() {
return new File(globalScope.getIntermediatesDir() + "/symbols/" +
variantData.getVariantConfiguration().getDirName());
}
@NonNull
public File getFinalResourcesDir() {
return Objects.firstNonNull(resourceOutputDir, getDefaultMergeResourcesOutputDir());
}
public void setResourceOutputDir(@NonNull File resourceOutputDir) {
this.resourceOutputDir = resourceOutputDir;
}
@NonNull
public File getDefaultMergeResourcesOutputDir() {
return new File(globalScope.getIntermediatesDir(),
"/res/merged/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getMergeResourcesOutputDir() {
if (mergeResourceOutputDir == null) {
return getDefaultMergeResourcesOutputDir();
}
return mergeResourceOutputDir;
}
public void setMergeResourceOutputDir(@Nullable File mergeResourceOutputDir) {
this.mergeResourceOutputDir = mergeResourceOutputDir;
}
@NonNull
public File getMergeAssetsOutputDir() {
return getVariantConfiguration().getType() == VariantType.LIBRARY ?
new File(globalScope.getIntermediatesDir(),
DIR_BUNDLES + "/" + getVariantConfiguration().getDirName() +
"/assets") :
new File(globalScope.getIntermediatesDir(),
"/assets/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getBuildConfigSourceOutputDir() {
return new File(globalScope.getBuildDir() + "/" + FD_GENERATED + "/source/buildConfig/"
+ variantData.getVariantConfiguration().getDirName());
}
@NonNull
public File getGeneratedResourcesDir(String name) {
return FileUtils.join(
globalScope.getGeneratedDir(),
"res",
name,
getVariantConfiguration().getDirName());
}
@NonNull
public File getGeneratedResOutputDir() {
return getGeneratedResourcesDir("resValues");
}
@NonNull
public File getGeneratedPngsOutputDir() {
return getGeneratedResourcesDir("pngs");
}
@NonNull
public File getRenderscriptResOutputDir() {
return getGeneratedResourcesDir("rs");
}
@NonNull
public File getPackagedJarsJavaResDestinationDir() {
return new File(globalScope.getIntermediatesDir(),
"packagedJarsJavaResources/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getSourceFoldersJavaResDestinationDir() {
return new File(globalScope.getIntermediatesDir(),
"sourceFolderJavaResources/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getJavaResourcesDestinationDir() {
return new File(globalScope.getIntermediatesDir(),
"javaResources/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getRClassSourceOutputDir() {
return new File(globalScope.getGeneratedDir(),
"source/r/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getAidlSourceOutputDir() {
return new File(globalScope.getGeneratedDir(),
"source/aidl/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getAidlIncrementalDir() {
return new File(globalScope.getIntermediatesDir(),
"incremental/aidl/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getAidlParcelableDir() {
return new File(globalScope.getIntermediatesDir(),
DIR_BUNDLES + "/" + getVariantConfiguration().getDirName() + "/aidl");
}
/**
* Returns the location of an intermediate directory that can be used by the Jack toolchain
* to store states necessary to support incremental compilation.
* @return a variant specific directory.
*/
@NonNull
public File getJackIncrementalDir() {
return new File(globalScope.getIntermediatesDir(),
"incremental/jack/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getJackTempDir() {
return new File(globalScope.getIntermediatesDir(),
"tmp/jack/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getJillPackagedLibrariesDir() {
return new File(globalScope.getIntermediatesDir(),
"jill/" + getVariantConfiguration().getDirName() + "/packaged");
}
@NonNull
public File getJillRuntimeLibrariesDir() {
return new File(globalScope.getIntermediatesDir(),
"jill/" + getVariantConfiguration().getDirName() + "/runtime");
}
@NonNull
public File getJackDestinationDir() {
return new File(globalScope.getIntermediatesDir(),
"dex/" + getVariantConfiguration().getDirName());
}
@NonNull
public File getJackClassesZip() {
return new File(globalScope.getIntermediatesDir(),
"packaged/" + getVariantConfiguration().getDirName() + "/classes.zip");
}
@NonNull
public File getProguardOutputFolder() {
return new File(globalScope.getBuildDir(), "/" + FD_OUTPUTS + "/mapping/" +
getVariantConfiguration().getDirName());
}
@NonNull
public File getProcessAndroidResourcesProguardOutputFile() {
return new File(globalScope.getIntermediatesDir(),
"/proguard-rules/" + getVariantConfiguration().getDirName() + "/aapt_rules.txt");
}
public File getMappingFile() {
return new File(globalScope.getOutputsDir(),
"/mapping/" + getVariantConfiguration().getDirName() + "/mapping.txt");
}
// Tasks getters/setters.
public AndroidTask<Task> getPreBuildTask() {
return preBuildTask;
}
public void setPreBuildTask(
AndroidTask<Task> preBuildTask) {
this.preBuildTask = preBuildTask;
}
public AndroidTask<PrepareDependenciesTask> getPrepareDependenciesTask() {
return prepareDependenciesTask;
}
public void setPrepareDependenciesTask(
AndroidTask<PrepareDependenciesTask> prepareDependenciesTask) {
this.prepareDependenciesTask = prepareDependenciesTask;
}
public AndroidTask<ProcessAndroidResources> getGenerateRClassTask() {
return generateRClassTask;
}
public void setGenerateRClassTask(
AndroidTask<ProcessAndroidResources> generateRClassTask) {
this.generateRClassTask = generateRClassTask;
}
public AndroidTask<Task> getSourceGenTask() {
return sourceGenTask;
}
public void setSourceGenTask(
AndroidTask<Task> sourceGenTask) {
this.sourceGenTask = sourceGenTask;
}
public AndroidTask<Task> getResourceGenTask() {
return resourceGenTask;
}
public void setResourceGenTask(
AndroidTask<Task> resourceGenTask) {
this.resourceGenTask = resourceGenTask;
}
public AndroidTask<Task> getAssetGenTask() {
return assetGenTask;
}
public void setAssetGenTask(
AndroidTask<Task> assetGenTask) {
this.assetGenTask = assetGenTask;
}
public AndroidTask<CheckManifest> getCheckManifestTask() {
return checkManifestTask;
}
public void setCheckManifestTask(
AndroidTask<CheckManifest> checkManifestTask) {
this.checkManifestTask = checkManifestTask;
}
public AndroidTask<RenderscriptCompile> getRenderscriptCompileTask() {
return renderscriptCompileTask;
}
public void setRenderscriptCompileTask(
AndroidTask<RenderscriptCompile> renderscriptCompileTask) {
this.renderscriptCompileTask = renderscriptCompileTask;
}
public AndroidTask<AidlCompile> getAidlCompileTask() {
return aidlCompileTask;
}
public void setAidlCompileTask(
AndroidTask<AidlCompile> aidlCompileTask) {
this.aidlCompileTask = aidlCompileTask;
}
@Nullable
public AndroidTask<MergeResources> getMergeResourcesTask() {
return mergeResourcesTask;
}
public void setMergeResourcesTask(
@Nullable AndroidTask<MergeResources> mergeResourcesTask) {
this.mergeResourcesTask = mergeResourcesTask;
}
@Nullable
public AndroidTask<MergeAssets> getMergeAssetsTask() {
return mergeAssetsTask;
}
public void setMergeAssetsTask(
@Nullable AndroidTask<MergeAssets> mergeAssetsTask) {
this.mergeAssetsTask = mergeAssetsTask;
}
public AndroidTask<GenerateBuildConfig> getGenerateBuildConfigTask() {
return generateBuildConfigTask;
}
public void setGenerateBuildConfigTask(
AndroidTask<GenerateBuildConfig> generateBuildConfigTask) {
this.generateBuildConfigTask = generateBuildConfigTask;
}
public AndroidTask<GenerateResValues> getGenerateResValuesTask() {
return generateResValuesTask;
}
public void setGenerateResValuesTask(
AndroidTask<GenerateResValues> generateResValuesTask) {
this.generateResValuesTask = generateResValuesTask;
}
@Nullable
public AndroidTask<Dex> getDexTask() {
return dexTask;
}
public void setDexTask(@Nullable AndroidTask<Dex> dexTask) {
this.dexTask = dexTask;
}
public AndroidTask<Sync> getProcessJavaResourcesTask() {
return processJavaResourcesTask;
}
public void setProcessJavaResourcesTask(
AndroidTask<Sync> processJavaResourcesTask) {
this.processJavaResourcesTask = processJavaResourcesTask;
}
SignedJarBuilder.IZipEntryFilter packagingOptionsFilter;
public void setPackagingOptionsFilter(SignedJarBuilder.IZipEntryFilter filter) {
this.packagingOptionsFilter = filter;
}
/**
* Returns the {@link SignedJarBuilder.IZipEntryFilter} instance
* that manages all resources inclusion in the final APK following the rules defined in
* {@link com.android.builder.model.PackagingOptions} settings.
*/
public SignedJarBuilder.IZipEntryFilter getPackagingOptionsFilter() {
return packagingOptionsFilter;
}
public void setMergeJavaResourcesTask(AndroidTask<MergeJavaResourcesTask> mergeJavaResourcesTask) {
this.mergeJavaResourcesTask = mergeJavaResourcesTask;
}
/**
* Returns the task extracting java resources from libraries and merging those with java
* resources coming from the variant's source folders.
* @return the task merging resources.
*/
public AndroidTask<MergeJavaResourcesTask> getMergeJavaResourcesTask() {
return mergeJavaResourcesTask;
}
public void setJavaResourcesProvider(JavaResourcesProvider javaResourcesProvider) {
this.javaResourcesProvider = javaResourcesProvider;
}
/**
* Returns the {@link JavaResourcesProvider} responsible for providing final merged and possibly
* obfuscated java resources for inclusion in the final APK. The provider might change during
* the variant build process.
* @return the java resources provider.
*/
public JavaResourcesProvider getJavaResourcesProvider() {
return javaResourcesProvider;
}
@Nullable
public AndroidTask<? extends AbstractCompile> getJavaCompilerTask() {
return javaCompilerTask;
}
@Nullable
public AndroidTask<JackTask> getJackTask() {
return jackTask;
}
public void setJackTask(
@Nullable AndroidTask<JackTask> jackTask) {
this.jackTask = jackTask;
}
@Nullable
public AndroidTask<JavaCompile> getJavacTask() {
return javacTask;
}
public void setJavacTask(
@Nullable AndroidTask<JavaCompile> javacTask) {
this.javacTask = javacTask;
}
public void setJavaCompilerTask(
@NonNull AndroidTask<? extends AbstractCompile> javaCompileTask) {
this.javaCompilerTask = javaCompileTask;
}
public AndroidTask<Task> getCompileTask() {
return compileTask;
}
public void setCompileTask(
AndroidTask<Task> compileTask) {
this.compileTask = compileTask;
}
public AndroidTask<? extends Task> getObfuscationTask() {
return obfuscationTask;
}
public void setObfuscationTask(
AndroidTask<? extends Task> obfuscationTask) {
this.obfuscationTask = obfuscationTask;
}
}