All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.build.gradle.tasks.MergeManifests Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
/*
 * 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 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;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy