private ResourceDirectoriesFromAapt addAaptPackageSteps()

in src/com/facebook/buck/android/AndroidBinaryRule.java [536:675]


  private ResourceDirectoriesFromAapt addAaptPackageSteps(ImmutableList.Builder<Step> steps,
      final AndroidTransitiveDependencies transitiveDependencies,
      final AndroidDexTransitiveDependencies dexTransitiveDependencies) {
    final Set<String> rDotJavaPackages = transitiveDependencies.rDotJavaPackages;
    final FilterResourcesStep filterResourcesStep;
    final ImmutableSet<String> resDirectories;
    if (requiresResourceFilter()) {
      filterResourcesStep = createFilterResourcesStep(transitiveDependencies.resDirectories);
      resDirectories = filterResourcesStep.getOutputResourceDirs();
      steps.add(filterResourcesStep);
    } else {
      filterResourcesStep = null;
      resDirectories = transitiveDependencies.resDirectories;
    }

    // Extract the resources from third-party jars.
    // TODO(mbolin): The results of this should be cached between runs.
    String extractedResourcesDir = getBinPath("__resources__%s__");
    steps.add(new MakeCleanDirectoryStep(extractedResourcesDir));
    steps.add(new ExtractResourcesStep(dexTransitiveDependencies.pathsToThirdPartyJars,
        extractedResourcesDir));

    // Create the R.java files. Their compiled versions must be included in classes.dex.
    // TODO(mbolin): Skip this step if the transitive set of AndroidResourceRules is cached.
    if (!resDirectories.isEmpty()) {
      UberRDotJavaUtil.generateRDotJavaFiles(resDirectories,
          rDotJavaPackages,
          getBuildTarget(),
          steps);

      if (isStoreStringsAsAssets()) {
        Path tmpStringsDirPath = getPathForTmpStringAssetsDirectory();
        steps.add(new MakeCleanDirectoryStep(tmpStringsDirPath));
        steps.add(new CompileStringsStep(
            filterResourcesStep,
            Paths.get(UberRDotJavaUtil.getPathToGeneratedRDotJavaSrcFiles(getBuildTarget())),
            tmpStringsDirPath));
      }
    }

    // Copy the transitive closure of files in assets to a single directory, if any.
    Step collectAssets = new Step() {
      @Override
      public int execute(ExecutionContext context) {
        // This must be done in a Command because the files and directories that are specified may
        // not exist at the time this Command is created because the previous Commands have not run
        // yet.
        ImmutableList.Builder<Step> commands = ImmutableList.builder();
        try {
          createAllAssetsDirectory(
              transitiveDependencies.assetsDirectories,
              commands,
              new DefaultDirectoryTraverser());
        } catch (IOException e) {
          context.logError(e, "Error creating all assets directory in %s.", getBuildTarget());
          return 1;
        }

        for (Step command : commands.build()) {
          int exitCode = command.execute(context);
          if (exitCode != 0) {
            throw new HumanReadableException("Error running " + command.getDescription(context));
          }
        }

        return 0;
      }

      @Override
      public String getShortName() {
        return "symlink_assets";
      }

      @Override
      public String getDescription(ExecutionContext context) {
        return getShortName();
      }
    };
    steps.add(collectAssets);

    // Copy the transitive closure of files in native_libs to a single directory, if any.
    ImmutableSet<String> nativeLibraryDirectories;
    if (!transitiveDependencies.nativeLibsDirectories.isEmpty()) {
      ImmutableSet.Builder<String> nativeLibraryDirectoriesBuilder = ImmutableSet.builder();
      String pathForNativeLibs = getPathForNativeLibs();
      String libSubdirectory = pathForNativeLibs + "/lib";
      nativeLibraryDirectoriesBuilder.add(libSubdirectory);
      steps.add(new MakeCleanDirectoryStep(libSubdirectory));
      for (String nativeLibDir : transitiveDependencies.nativeLibsDirectories) {
        copyNativeLibrary(nativeLibDir, libSubdirectory, steps);
      }
      nativeLibraryDirectories = nativeLibraryDirectoriesBuilder.build();
    } else {
      nativeLibraryDirectories = ImmutableSet.of();
    }

    Optional<String> assetsDirectory;
    if (transitiveDependencies.assetsDirectories.isEmpty()
        && transitiveDependencies.nativeLibAssetsDirectories.isEmpty()
        && !isStoreStringsAsAssets()) {
      assetsDirectory = Optional.absent();
    } else {
      assetsDirectory = Optional.of(getPathToAllAssetsDirectory());
    }

    if (!transitiveDependencies.nativeLibAssetsDirectories.isEmpty()) {
      String nativeLibAssetsDir = assetsDirectory.get() + "/lib";
      steps.add(new MakeCleanDirectoryStep(nativeLibAssetsDir));
      for (String nativeLibDir : transitiveDependencies.nativeLibAssetsDirectories) {
        copyNativeLibrary(nativeLibDir, nativeLibAssetsDir, steps);
      }
    }

    if (isStoreStringsAsAssets()) {
      Path stringAssetsDir = Paths.get(assetsDirectory.get()).resolve("strings");
      steps.add(new MakeCleanDirectoryStep(stringAssetsDir));
      steps.add(new CopyStep(
          getPathForTmpStringAssetsDirectory(),
          stringAssetsDir,
          /* shouldRecurse */ true));
    }

    steps.add(new MkdirStep(outputGenDirectory));

    if (!canSkipAaptResourcePackaging()) {
      AaptStep aaptCommand = new AaptStep(
          getAndroidManifestXml(),
          resDirectories,
          assetsDirectory,
          getResourceApkPath(),
          ImmutableSet.of(extractedResourcesDir),
          packageType.isCrunchPngFiles());
      steps.add(aaptCommand);
    }

    ResourceDirectoriesFromAapt resourceDirectoriesFromAapt = new ResourceDirectoriesFromAapt(
        resDirectories,
        nativeLibraryDirectories);
    return resourceDirectoriesFromAapt;
  }