com.facebook.buck.android.AndroidAarDescription.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.android.AndroidAarDescription.java

Source

/*
 * Copyright 2015-present Facebook, Inc.
 *
 * 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.facebook.buck.android;

import com.facebook.buck.android.aapt.MergeAndroidResourceSources;
import com.facebook.buck.cxx.CxxBuckConfig;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.model.UnflavoredBuildTarget;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.Description;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.infer.annotation.SuppressFieldNotInitialized;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;

import java.nio.file.Path;
import java.util.Optional;

/**
 * Description for a {@link BuildRule} that generates an {@code .aar} file.
 * <p/>
 * This represents an Android Library Project packaged as an {@code .aar} bundle as specified by:
 * <a> http://tools.android.com/tech-docs/new-build-system/aar-format</a>.
 * <p/>
 * Note that the {@code aar} may be specified as a {@link SourcePath}, so it could be either
 * a binary {@code .aar} file checked into version control, or a zip file that conforms to the
 * {@code .aar} specification that is generated by another build rule.
 */
public class AndroidAarDescription implements Description<AndroidAarDescription.Arg> {

    private static final Flavor AAR_ANDROID_MANIFEST_FLAVOR = ImmutableFlavor.of("aar_android_manifest");
    private static final Flavor AAR_ASSEMBLE_RESOURCE_FLAVOR = ImmutableFlavor.of("aar_assemble_resource");
    private static final Flavor AAR_ASSEMBLE_ASSETS_FLAVOR = ImmutableFlavor.of("aar_assemble_assets");
    private static final Flavor AAR_ANDROID_RESOURCE_FLAVOR = ImmutableFlavor.of("aar_android_resource");

    private final AndroidManifestDescription androidManifestDescription;
    private final CxxBuckConfig cxxBuckConfig;
    private final ImmutableMap<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> nativePlatforms;

    public AndroidAarDescription(AndroidManifestDescription androidManifestDescription, CxxBuckConfig cxxBuckConfig,
            ImmutableMap<NdkCxxPlatforms.TargetCpuType, NdkCxxPlatform> nativePlatforms) {
        this.androidManifestDescription = androidManifestDescription;
        this.cxxBuckConfig = cxxBuckConfig;
        this.nativePlatforms = nativePlatforms;
    }

    @Override
    public Arg createUnpopulatedConstructorArg() {
        return new Arg();
    }

    @Override
    public <A extends Arg> BuildRule createBuildRule(TargetGraph targetGraph,
            BuildRuleParams originalBuildRuleParams, BuildRuleResolver resolver, A args)
            throws NoSuchBuildTargetException {

        UnflavoredBuildTarget originalBuildTarget = originalBuildRuleParams.getBuildTarget().checkUnflavored();
        SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
        SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
        ImmutableList.Builder<BuildRule> aarExtraDepsBuilder = ImmutableList.<BuildRule>builder()
                .addAll(originalBuildRuleParams.getExtraDeps().get());

        /* android_manifest */
        AndroidManifestDescription.Arg androidManifestArgs = androidManifestDescription
                .createUnpopulatedConstructorArg();
        androidManifestArgs.skeleton = args.manifestSkeleton;
        androidManifestArgs.deps = args.deps;

        BuildRuleParams androidManifestParams = originalBuildRuleParams.copyWithChanges(
                BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ANDROID_MANIFEST_FLAVOR),
                originalBuildRuleParams.getDeclaredDeps(), originalBuildRuleParams.getExtraDeps());

        AndroidManifest manifest = androidManifestDescription.createBuildRule(targetGraph, androidManifestParams,
                resolver, androidManifestArgs);
        aarExtraDepsBuilder.add(resolver.addToIndex(manifest));

        final APKModuleGraph apkModuleGraph = new APKModuleGraph(targetGraph,
                originalBuildRuleParams.getBuildTarget(), Optional.empty());

        /* assemble dirs */
        AndroidPackageableCollector collector = new AndroidPackageableCollector(
                originalBuildRuleParams.getBuildTarget(), /* buildTargetsToExcludeFromDex */ ImmutableSet.of(),
                /* resourcesToExclude */ ImmutableSet.of(), apkModuleGraph);
        collector.addPackageables(
                AndroidPackageableCollector.getPackageableRules(originalBuildRuleParams.getDeps()));
        AndroidPackageableCollection packageableCollection = collector.build();

        ImmutableSortedSet<BuildRule> androidResourceDeclaredDeps = AndroidResourceHelper
                .androidResOnly(originalBuildRuleParams.getDeclaredDeps().get());
        ImmutableSortedSet<BuildRule> androidResourceExtraDeps = AndroidResourceHelper
                .androidResOnly(originalBuildRuleParams.getExtraDeps().get());

        BuildRuleParams assembleAssetsParams = originalBuildRuleParams.copyWithChanges(
                BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ASSEMBLE_ASSETS_FLAVOR),
                Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps));
        ImmutableCollection<SourcePath> assetsDirectories = packageableCollection.getAssetsDirectories();
        AssembleDirectories assembleAssetsDirectories = new AssembleDirectories(assembleAssetsParams, pathResolver,
                assetsDirectories);
        aarExtraDepsBuilder.add(resolver.addToIndex(assembleAssetsDirectories));

        BuildRuleParams assembleResourceParams = originalBuildRuleParams.copyWithChanges(
                BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ASSEMBLE_RESOURCE_FLAVOR),
                Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps));
        ImmutableCollection<SourcePath> resDirectories = packageableCollection.getResourceDetails()
                .getResourceDirectories();
        MergeAndroidResourceSources assembleResourceDirectories = new MergeAndroidResourceSources(
                assembleResourceParams, pathResolver, resDirectories);
        aarExtraDepsBuilder.add(resolver.addToIndex(assembleResourceDirectories));

        /* android_resource */
        BuildRuleParams androidResourceParams = originalBuildRuleParams.copyWithChanges(
                BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR),
                Suppliers.ofInstance(
                        ImmutableSortedSet.of(manifest, assembleAssetsDirectories, assembleResourceDirectories)),
                Suppliers.ofInstance(ImmutableSortedSet.of()));

        AndroidResource androidResource = new AndroidResource(androidResourceParams, ruleFinder,
                /* deps */ ImmutableSortedSet.<BuildRule>naturalOrder().add(assembleAssetsDirectories)
                        .add(assembleResourceDirectories).addAll(originalBuildRuleParams.getDeclaredDeps().get())
                        .build(),
                new BuildTargetSourcePath(assembleResourceDirectories.getBuildTarget()),
                /* resSrcs */ ImmutableSortedSet.of(), Optional.empty(), /* rDotJavaPackage */ null,
                new BuildTargetSourcePath(assembleAssetsDirectories.getBuildTarget()),
                /* assetsSrcs */ ImmutableSortedSet.of(), Optional.empty(),
                new BuildTargetSourcePath(manifest.getBuildTarget()), /* hasWhitelistedStrings */ false);
        aarExtraDepsBuilder.add(resolver.addToIndex(androidResource));

        /* native_libraries */
        AndroidNativeLibsPackageableGraphEnhancer packageableGraphEnhancer = new AndroidNativeLibsPackageableGraphEnhancer(
                resolver, originalBuildRuleParams, nativePlatforms, ImmutableSet.of(), cxxBuckConfig,
                /* nativeLibraryMergeMap */ Optional.empty(), /* nativeLibraryMergeGlue */ Optional.empty(),
                AndroidBinary.RelinkerMode.DISABLED, apkModuleGraph);
        Optional<ImmutableMap<APKModule, CopyNativeLibraries>> nativeLibrariesOptional = packageableGraphEnhancer
                .enhance(packageableCollection).getCopyNativeLibraries();
        if (nativeLibrariesOptional.isPresent()
                && nativeLibrariesOptional.get().containsKey(apkModuleGraph.getRootAPKModule())) {
            aarExtraDepsBuilder
                    .add(resolver.addToIndex(nativeLibrariesOptional.get().get(apkModuleGraph.getRootAPKModule())));
        }

        Optional<Path> assembledNativeLibsDir = nativeLibrariesOptional.map(input -> {
            // there will be only one value for the root module
            CopyNativeLibraries copyNativeLibraries = input.get(apkModuleGraph.getRootAPKModule());
            if (copyNativeLibraries == null) {
                throw new HumanReadableException(
                        "Native libraries are present but not in the root application module.");
            }
            return copyNativeLibraries.getPathToNativeLibsDir();
        });
        BuildRuleParams androidAarParams = originalBuildRuleParams
                .copyWithExtraDeps(Suppliers.ofInstance(ImmutableSortedSet.copyOf(aarExtraDepsBuilder.build())));
        return new AndroidAar(androidAarParams, manifest, androidResource,
                assembleResourceDirectories.getPathToOutput(), assembleAssetsDirectories.getPathToOutput(),
                assembledNativeLibsDir,
                ImmutableSet.copyOf(packageableCollection.getNativeLibAssetsDirectories().values()));
    }

    @SuppressFieldNotInitialized
    public static class Arg extends AndroidLibraryDescription.Arg {
        public SourcePath manifestSkeleton;
    }
}