aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java
diff options
context:
space:
mode:
authorGravatar Andrew Pellegrini <apell@google.com>2016-06-22 20:46:21 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-06-23 11:10:23 +0000
commite1a4a812971f604d51bdf098b6117d9ba03da1c8 (patch)
treed53b64a6f80fb82cfa43d65c9b3f2f73b9084cdf /src/tools/android/java
parent6105e2415faa0f36ec6ae3399d90e1a173ef7f58 (diff)
Adds the Android manifest merger as an option for android_binary rules. The merger that is used (legacy or android) is controlled by the manifest_merger attribute on android_binary and the default is controlled by the --android_manifest_merger flag.
RELNOTES: The Android manifest merger is now available as an option for android_binary rules. The merger will honor tools annotations in AndroidManifest.xml and will perform placeholder substitutions using the values specified in android_binary.manifest_values. The merger may be selected by setting the manifest_merger attribute on android_binary. -- MOS_MIGRATED_REVID=125603954
Diffstat (limited to 'src/tools/android/java')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java36
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD.tools16
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java49
3 files changed, 88 insertions, 13 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
index 69f58d6fbb..9bbef3dd24 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.android;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -30,6 +32,7 @@ import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.TriState;
import com.android.builder.core.VariantConfiguration;
+import com.android.builder.core.VariantConfiguration.Type;
import com.android.ide.common.internal.AaptCruncher;
import com.android.ide.common.internal.CommandLineRunner;
import com.android.ide.common.internal.LoggedErrorException;
@@ -40,6 +43,7 @@ import com.android.utils.StdLogger;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -226,6 +230,7 @@ public class AndroidResourceProcessingAction {
final Path filteredResources = tmp.resolve("resources-filtered");
final Path densityManifest = tmp.resolve("manifest-filtered/AndroidManifest.xml");
final Path processedManifest = tmp.resolve("manifest-processed/AndroidManifest.xml");
+ final Path dummyManifest = tmp.resolve("manifest-aapt-dummy/AndroidManifest.xml");
Path generatedSources = null;
if (options.srcJarOutput != null || options.rOutput != null
@@ -266,7 +271,7 @@ public class AndroidResourceProcessingAction {
LOGGER.fine(String.format("Density filtering finished at %sms",
timer.elapsed(TimeUnit.MILLISECONDS)));
- final MergedAndroidData processedManifestData = resourceProcessor.processManifest(
+ MergedAndroidData processedData = resourceProcessor.processManifest(
options.packageType,
options.packageForR,
options.applicationId,
@@ -275,6 +280,24 @@ public class AndroidResourceProcessingAction {
filteredData,
processedManifest);
+ // Write manifestOutput now before the dummy manifest is created.
+ if (options.manifestOutput != null) {
+ resourceProcessor.copyManifestToOutput(processedData, options.manifestOutput);
+ }
+
+ if (options.packageType == Type.LIBRARY) {
+ Files.createDirectories(dummyManifest.getParent());
+ Files.write(dummyManifest, String.format(
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\""
+ + " package=\"%s\">"
+ + "</manifest>", options.packageForR).getBytes(UTF_8));
+ processedData = new MergedAndroidData(
+ processedData.getResourceDir(),
+ processedData.getAssetDir(),
+ dummyManifest);
+ }
+
resourceProcessor.processResources(
aaptConfigOptions.aapt,
aaptConfigOptions.androidJar,
@@ -285,20 +308,17 @@ public class AndroidResourceProcessingAction {
new FlagAaptOptions(aaptConfigOptions),
aaptConfigOptions.resourceConfigs,
aaptConfigOptions.splits,
- processedManifestData,
+ processedData,
data,
generatedSources,
options.packagePath,
options.proguardOutput,
options.mainDexProguardOutput,
options.resourcesOutput != null
- ? processedManifestData.getResourceDir().resolve("values").resolve("public.xml")
+ ? processedData.getResourceDir().resolve("values").resolve("public.xml")
: null);
LOGGER.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
- if (options.manifestOutput != null) {
- resourceProcessor.copyManifestToOutput(processedManifestData, options.manifestOutput);
- }
if (options.srcJarOutput != null) {
resourceProcessor.createSrcJar(generatedSources, options.srcJarOutput,
VariantConfiguration.Type.LIBRARY == options.packageType);
@@ -312,8 +332,8 @@ public class AndroidResourceProcessingAction {
VariantConfiguration.Type.LIBRARY == options.packageType);
}
if (options.resourcesOutput != null) {
- resourceProcessor.createResourcesZip(processedManifestData.getResourceDir(),
- processedManifestData.getAssetDir(), options.resourcesOutput);
+ resourceProcessor.createResourcesZip(processedData.getResourceDir(),
+ processedData.getAssetDir(), options.resourcesOutput);
}
LOGGER.fine(String.format("Packaging finished at %sms",
timer.elapsed(TimeUnit.MILLISECONDS)));
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
index 1d5da32118..d844ff9553 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
@@ -6,6 +6,14 @@ java_import(
)
java_binary(
+ name = "AarGeneratorAction",
+ main_class = "com.google.devtools.build.android.AarGeneratorAction",
+ runtime_deps = [
+ ":classes",
+ ],
+)
+
+java_binary(
name = "AndroidResourceCompilationAction",
main_class = "com.google.devtools.build.android.AndroidResourceCompilationAction",
runtime_deps = [
@@ -22,16 +30,16 @@ java_binary(
)
java_binary(
- name = "ResourceShrinkerAction",
- main_class = "com.google.devtools.build.android.ResourceShrinkerAction",
+ name = "ManifestMergerAction",
+ main_class = "com.google.devtools.build.android.ManifestMergerAction",
runtime_deps = [
":classes",
],
)
java_binary(
- name = "AarGeneratorAction",
- main_class = "com.google.devtools.build.android.AarGeneratorAction",
+ name = "ResourceShrinkerAction",
+ main_class = "com.google.devtools.build.android.ResourceShrinkerAction",
runtime_deps = [
":classes",
],
diff --git a/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java b/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
index 4a8f0a5500..ce1884d6a4 100644
--- a/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/ManifestMergerAction.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.android;
import static java.util.logging.Level.SEVERE;
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.Converters.ExistingPathConverter;
import com.google.devtools.build.android.Converters.ExistingPathListConverter;
import com.google.devtools.build.android.Converters.MergeTypeConverter;
@@ -27,6 +28,11 @@ import com.google.devtools.common.options.OptionsParser;
import com.android.manifmerger.ManifestMerger2.MergeType;
import com.android.utils.StdLogger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -36,6 +42,16 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
/**
* An action to perform manifest merging using the Gradle manifest merger.
*
@@ -102,11 +118,34 @@ public class ManifestMergerAction {
public Path manifestOutput;
}
+ private static final String[] PERMISSION_TAGS =
+ new String[] {"uses-permission", "uses-permission-sdk-23"};
private static final StdLogger stdLogger = new StdLogger(StdLogger.Level.WARNING);
private static final Logger logger = Logger.getLogger(ManifestMergerAction.class.getName());
private static Options options;
+ private static Path removePermissions(Path manifest, Path outputDir)
+ throws IOException, ParserConfigurationException, TransformerConfigurationException,
+ TransformerException, TransformerFactoryConfigurationError, SAXException {
+ DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = docBuilder.parse(manifest.toFile());
+ for (String tag : PERMISSION_TAGS) {
+ NodeList permissions = doc.getElementsByTagName(tag);
+ if (permissions != null) {
+ for (int i = permissions.getLength() - 1; i >= 0; i--) {
+ Node permission = permissions.item(i);
+ permission.getParentNode().removeChild(permission);
+ }
+ }
+ }
+ Path output = outputDir.resolve(manifest.getFileName());
+ TransformerFactory.newInstance().newTransformer().transform(
+ new DOMSource(doc),
+ new StreamResult(output.toFile()));
+ return output;
+ }
+
public static void main(String[] args) throws Exception {
OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
optionsParser.parseAndExitUponError(args);
@@ -117,10 +156,18 @@ public class ManifestMergerAction {
try {
Path mergedManifest;
if (options.mergeType == MergeType.APPLICATION) {
+ // Remove uses-permission tags from mergees before the merge.
+ Path tmp = Files.createTempDirectory("manifest_merge_tmp");
+ tmp.toFile().deleteOnExit();
+ ImmutableList.Builder<Path> mergeeManifests = ImmutableList.builder();
+ for (Path mergeeManifest : options.mergeeManifests) {
+ mergeeManifests.add(removePermissions(mergeeManifest, tmp));
+ }
+
// Ignore custom package at the binary level.
mergedManifest = resourceProcessor.mergeManifest(
options.manifest,
- options.mergeeManifests,
+ mergeeManifests.build(),
options.mergeType,
options.manifestValues,
options.manifestOutput);