blob: 59d27a4e36f239aad162becf6fd6d842d2e6b1d0 [file] [log] [blame]
/*
* Copyright 2012-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.android.sdklib.build.ApkBuilder;
import com.facebook.buck.shell.ShellStep;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.util.AndroidPlatformTarget;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
/**
* Runs the Android Asset Packaging Tool ({@code aapt}), which creates an {@code .apk} file.
* Frequently, the {@code pathsToRawFilesDirs} excludes {@code classes.dex}, as {@code classes.dex}
* will be added separately to the final APK via {@link ApkBuilder}.
*/
public class AaptStep extends ShellStep {
private final String androidManifest;
private final Set<String> resDirectories;
private final Optional<String> assetsDirectory;
private final String pathToOutputApkFile;
private final Set<String> pathsToRawFilesDirs;
@SuppressWarnings("unused")
private final boolean isCrunchPngFiles;
public AaptStep(
String androidManifest,
Set<String> resDirectories,
Optional<String> assetsDirectory,
String pathToOutputApkFile,
Set<String> pathsToRawFilesDirs,
boolean isCrunchPngFiles) {
this.androidManifest = Preconditions.checkNotNull(androidManifest);
this.resDirectories = ImmutableSet.copyOf(resDirectories);
this.assetsDirectory = Preconditions.checkNotNull(assetsDirectory);
this.pathToOutputApkFile = Preconditions.checkNotNull(pathToOutputApkFile);
this.pathsToRawFilesDirs = ImmutableSet.copyOf(pathsToRawFilesDirs);
this.isCrunchPngFiles = isCrunchPngFiles;
}
@Override
protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) {
ImmutableList.Builder<String> builder = ImmutableList.builder();
AndroidPlatformTarget androidPlatformTarget = context.getAndroidPlatformTarget();
builder.add(androidPlatformTarget.getAaptExecutable().getAbsolutePath(), "package");
// verbose flag, if appropriate.
if (context.getVerbosity().shouldUseVerbosityFlagIfAvailable()) {
builder.add("-v");
}
// Force overwrite of existing files.
builder.add("-f");
/*
* In practice, it appears that if --no-crunch is used, resources will occasionally appear
* distorted in the APK produced by this command (and what's worse, a clean reinstall does not
* make the problem go away). This is not reliably reproducible, so for now, we categorically
* outlaw the use of --no-crunch so that developers do not get stuck in the distorted image
* state. One would expect the use of --no-crunch to allow for faster build times, so it would
* be nice to figure out a way to leverage it in debug mode that never results in distorted
* images.
*/
// --no-crunch, if appropriate.
// if (!isCrunchPngFiles) {
// builder.add("--no-crunch");
// }
// Include all of the res/ directories.
builder.add("--auto-add-overlay");
for (String res : resDirectories) {
builder.add("-S", res);
}
// Include the assets/ directory, if any.
// According to the aapt documentation, it appears that it should be possible to specify the -A
// flag multiple times; however, in practice, when it is specified multiple times, only one of
// the folders is included in the final APK.
if (assetsDirectory.isPresent()) {
builder.add("-A", assetsDirectory.get());
}
builder.add("-M").add(androidManifest);
builder.add("-I", androidPlatformTarget.getAndroidJar().getAbsolutePath());
builder.add("-F", pathToOutputApkFile);
builder.addAll(pathsToRawFilesDirs);
return builder.build();
}
@Override
public String getShortName() {
return String.format("aapt_package");
}
}