diff options
Diffstat (limited to 'src/tools/android/java/com/google/devtools')
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); |