com.android.build.gradle.tasks.MergeManifests Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-core Show documentation
Show all versions of gradle-core Show documentation
Core library to build Android Gradle plugin.
/*
* Copyright (C) 2012 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.annotations.NonNull;
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl;
import com.android.build.gradle.internal.dsl.CoreBuildType;
import com.android.build.gradle.internal.dsl.CoreProductFlavor;
import com.android.build.gradle.internal.scope.ConventionMappingHelper;
import com.android.build.gradle.internal.scope.TaskConfigAction;
import com.android.build.gradle.internal.scope.VariantOutputScope;
import com.android.build.gradle.internal.variant.ApkVariantOutputData;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.android.builder.core.VariantConfiguration;
import com.android.builder.dependency.LibraryDependency;
import com.android.builder.model.ApiVersion;
import com.android.manifmerger.ManifestMerger2;
import com.android.manifmerger.ManifestMerger2.Invoker.Feature;
import com.google.common.collect.Lists;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.ParallelizableTask;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
/**
* A task that processes the manifest
*/
@ParallelizableTask
public class MergeManifests extends ManifestProcessorTask {
private String minSdkVersion;
private String targetSdkVersion;
private Integer maxSdkVersion;
private File reportFile;
private VariantConfiguration
variantConfiguration;
private ApkVariantOutputData variantOutputData;
private List libraries;
private List optionalFeatures;
@Override
protected void doFullTaskAction() {
getBuilder().mergeManifests(
getMainManifest(),
getManifestOverlays(),
getLibraries(),
getPackageOverride(),
getVersionCode(),
getVersionName(),
getMinSdkVersion(),
getTargetSdkVersion(),
getMaxSdkVersion(),
getManifestOutputFile().getAbsolutePath(),
// no aapt friendly merged manifest file necessary for applications.
null /* aaptFriendlyManifestOutputFile */,
getInstantRunManifestOutputFile().getAbsolutePath(),
ManifestMerger2.MergeType.APPLICATION,
variantConfiguration.getManifestPlaceholders(),
getOptionalFeatures(),
getReportFile());
}
@InputFile
public File getMainManifest() {
return variantConfiguration.getMainManifest();
}
@InputFiles
public List getManifestOverlays() {
return variantConfiguration.getManifestOverlays();
}
@Input
@Optional
public String getPackageOverride() {
return variantConfiguration.getIdOverride();
}
@Input
public int getVersionCode() {
if (variantOutputData != null) {
return variantOutputData.getVersionCode();
}
return variantConfiguration.getVersionCode();
}
@Input
@Optional
public String getVersionName() {
if (variantOutputData != null) {
return variantOutputData.getVersionName();
}
return variantConfiguration.getVersionName();
}
/**
* Returns a serialized version of our map of key value pairs for placeholder substitution.
*
* This serialized form is only used by gradle to compare past and present tasks to determine
* whether a task need to be re-run or not.
*/
@SuppressWarnings("unused")
@Input
@Optional
public String getManifestPlaceholders() {
return serializeMap(variantConfiguration.getManifestPlaceholders());
}
/**
* A synthetic input to allow gradle up-to-date checks to work.
*
* Since List can't be used directly, as @Nested doesn't work on lists,
* this method gathers and returns the underlying manifest files.
*/
@SuppressWarnings("unused")
@InputFiles
List getLibraryManifests() {
List libs = getLibraries();
if (libs == null || libs.isEmpty()) {
return Collections.emptyList();
}
List files = Lists.newArrayListWithCapacity(libs.size() * 2);
for (ManifestDependencyImpl mdi : libs) {
files.addAll(mdi.getAllManifests());
}
return files;
}
@Input
@Optional
public String getMinSdkVersion() {
return minSdkVersion;
}
public void setMinSdkVersion(String minSdkVersion) {
this.minSdkVersion = minSdkVersion;
}
@Input
@Optional
public String getTargetSdkVersion() {
return targetSdkVersion;
}
public void setTargetSdkVersion(String targetSdkVersion) {
this.targetSdkVersion = targetSdkVersion;
}
@Input
@Optional
public Integer getMaxSdkVersion() {
return maxSdkVersion;
}
public void setMaxSdkVersion(Integer maxSdkVersion) {
this.maxSdkVersion = maxSdkVersion;
}
@OutputFile
@Optional
public File getReportFile() {
return reportFile;
}
public void setReportFile(File reportFile) {
this.reportFile = reportFile;
}
@Input
public List getOptionalFeatures() {
return optionalFeatures;
}
public VariantConfiguration getVariantConfiguration() {
return variantConfiguration;
}
public void setVariantConfiguration(
VariantConfiguration variantConfiguration) {
this.variantConfiguration = variantConfiguration;
}
public ApkVariantOutputData getVariantOutputData() {
return variantOutputData;
}
public void setVariantOutputData(ApkVariantOutputData variantOutputData) {
this.variantOutputData = variantOutputData;
}
public List getLibraries() {
return libraries;
}
public void setLibraries(List libraries) {
this.libraries = libraries;
}
public static class ConfigAction implements TaskConfigAction {
private final VariantOutputScope scope;
private final List optionalFeatures;
public ConfigAction(VariantOutputScope scope, List optionalFeatures) {
this.scope = scope;
this.optionalFeatures = optionalFeatures;
}
@NonNull
@Override
public String getName() {
return scope.getTaskName("process", "Manifest");
}
@NonNull
@Override
public Class getType() {
return MergeManifests.class;
}
@Override
public void execute(@NonNull MergeManifests processManifestTask) {
BaseVariantOutputData variantOutputData = scope.getVariantOutputData();
final BaseVariantData extends BaseVariantOutputData> variantData =
scope.getVariantScope().getVariantData();
final VariantConfiguration config =
variantData.getVariantConfiguration();
variantOutputData.manifestProcessorTask = processManifestTask;
processManifestTask.setAndroidBuilder(scope.getGlobalScope().getAndroidBuilder());
processManifestTask.setVariantName(config.getFullName());
processManifestTask.dependsOn(variantData.prepareDependenciesTask);
if (variantData.generateApkDataTask != null) {
processManifestTask.dependsOn(variantData.generateApkDataTask);
}
if (scope.getCompatibleScreensManifestTask() != null) {
processManifestTask.dependsOn(scope.getCompatibleScreensManifestTask().getName());
}
processManifestTask.setVariantConfiguration(config);
if (variantOutputData instanceof ApkVariantOutputData) {
processManifestTask.variantOutputData =
(ApkVariantOutputData) variantOutputData;
}
ConventionMappingHelper.map(processManifestTask, "libraries",
new Callable>() {
@Override
public List call() throws Exception {
List manifests =
getManifestDependencies(config.getDirectLibraries());
if (variantData.generateApkDataTask != null &&
variantData.getVariantConfiguration().getBuildType().
isEmbedMicroApp()) {
manifests.add(new ManifestDependencyImpl(
variantData.generateApkDataTask.getManifestFile(),
Collections.emptyList()));
}
if (scope.getCompatibleScreensManifestTask() != null) {
manifests.add(new ManifestDependencyImpl(
scope.getCompatibleScreensManifestFile(),
Collections.emptyList()));
}
return manifests;
}
});
ConventionMappingHelper.map(processManifestTask, "minSdkVersion",
new Callable() {
@Override
public String call() throws Exception {
if (scope.getGlobalScope().getAndroidBuilder().isPreviewTarget()) {
return scope.getGlobalScope().getAndroidBuilder()
.getTargetCodename();
}
ApiVersion minSdk = config.getMergedFlavor().getMinSdkVersion();
return minSdk == null ? null : minSdk.getApiString();
}
});
ConventionMappingHelper.map(processManifestTask, "targetSdkVersion",
new Callable() {
@Override
public String call() throws Exception {
if (scope.getGlobalScope().getAndroidBuilder().isPreviewTarget()) {
return scope.getGlobalScope().getAndroidBuilder()
.getTargetCodename();
}
ApiVersion targetSdk = config.getMergedFlavor().getTargetSdkVersion();
return targetSdk == null ? null : targetSdk.getApiString();
}
});
ConventionMappingHelper.map(processManifestTask, "maxSdkVersion",
new Callable() {
@Override
public Integer call() throws Exception {
if (scope.getGlobalScope().getAndroidBuilder().isPreviewTarget()) {
return null;
}
return config.getMergedFlavor().getMaxSdkVersion();
}
});
processManifestTask.setManifestOutputFile(scope.getManifestOutputFile());
processManifestTask.setInstantRunManifestOutputFile(
scope.getVariantScope().getInstantRunManifestOutputFile());
processManifestTask.setReportFile(scope.getVariantScope().getManifestReportFile());
processManifestTask.optionalFeatures = optionalFeatures;
}
@NonNull
private static List getManifestDependencies(
List libraries) {
List list = Lists.newArrayListWithCapacity(libraries.size());
for (LibraryDependency lib : libraries) {
if (!lib.isOptional()) {
// get the dependencies
List children =
getManifestDependencies(lib.getDependencies());
list.add(new ManifestDependencyImpl(lib.getName(), lib.getManifest(), children));
}
}
return list;
}
}
}