diff options
author | Googler <noreply@google.com> | 2017-12-15 12:44:32 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2017-12-15 12:46:43 -0800 |
commit | 70c2be189c9c0021f7c424c7399f8bdecc579b4e (patch) | |
tree | 3c5200626c3852044c8225fd672dc7501e511e07 /src/tools/android/java/com/google/devtools/build/android | |
parent | c4071e8b634440cf873b719dd948b8777b03f50e (diff) |
Use assets from the APK for resource shrinking rather than from the merge actions.
RELNOTES: none
PiperOrigin-RevId: 179227857
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android')
7 files changed, 70 insertions, 17 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java index c2ddb7cd9f..f2bfba4787 100644 --- a/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java @@ -195,14 +195,15 @@ public class Aapt2ResourcePackagingAction { profiler.startTask("package"); // The compiled resources and the merged resources should be the same. // TODO(corysmith): Decompile or otherwise provide the exact resources in the apk. - ResourcesZip.from( + ResourcesZip.fromApk( mergedAndroidData.getResourceDir(), - mergedAndroidData.getAssetDir(), - packagedResources.resourceIds()) + packagedResources.getApk(), + packagedResources.getResourceIds()) .writeTo(options.resourcesOutput, false /* compress */); profiler.recordEndOf("package"); } } } } + } diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java index 82001c6065..eaf0ae45bc 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java @@ -105,6 +105,12 @@ public class AndroidResourceOutputs { zip.closeEntry(); } + protected void addEntry(ZipEntry entry, byte[] content) throws IOException { + zip.putNextEntry(entry); + zip.write(content); + zip.closeEntry(); + } + @Override public void close() throws IOException { zip.close(); diff --git a/src/tools/android/java/com/google/devtools/build/android/ResourcesZip.java b/src/tools/android/java/com/google/devtools/build/android/ResourcesZip.java index edb254434c..5f2b644178 100644 --- a/src/tools/android/java/com/google/devtools/build/android/ResourcesZip.java +++ b/src/tools/android/java/com/google/devtools/build/android/ResourcesZip.java @@ -41,12 +41,18 @@ public class ResourcesZip { private final Path resourcesRoot; private final Path assetsRoot; + private final Optional<Path> apkWithAssets; private final Optional<Path> ids; - private ResourcesZip(Path resourcesRoot, Path assetsRoot, Optional<Path> ids) { + private ResourcesZip( + Path resourcesRoot, + Path assetsRoot, + Optional<Path> ids, + Optional<Path> apkWithAssets) { this.resourcesRoot = resourcesRoot; this.assetsRoot = assetsRoot; this.ids = ids; + this.apkWithAssets = apkWithAssets; } /** @@ -54,7 +60,7 @@ public class ResourcesZip { * @param assetsRoot The root of the raw assets. */ public static ResourcesZip from(Path resourcesRoot, Path assetsRoot) { - return new ResourcesZip(resourcesRoot, assetsRoot, Optional.empty()); + return new ResourcesZip(resourcesRoot, assetsRoot, Optional.empty(), Optional.empty()); } /** @@ -64,7 +70,23 @@ public class ResourcesZip { */ public static ResourcesZip from(Path resourcesRoot, Path assetsRoot, Path resourceIds) { return new ResourcesZip( - resourcesRoot, assetsRoot, Optional.of(resourceIds).filter(Files::exists)); + resourcesRoot, + assetsRoot, + Optional.of(resourceIds).filter(Files::exists), + Optional.empty()); + } + + /** + * @param resourcesRoot The root of the raw resources. + * @param apkWithAssets The apk containing assets. + * @param resourceIds Optional path to a file containing the resource ids. + */ + public static ResourcesZip fromApk(Path resourcesRoot, Path apkWithAssets, Path resourceIds) { + return new ResourcesZip( + resourcesRoot, + null /* assetsRoot */, + Optional.of(resourceIds).filter(Files::exists), + Optional.of(apkWithAssets)); } /** Creates a ResourcesZip from an archive by expanding into the workingDirectory. */ @@ -116,7 +138,24 @@ public class ResourcesZip { } visitor.writeEntries(); } - if (Files.exists(assetsRoot)) { + + if (apkWithAssets.isPresent()){ + ZipFile apkZip = new ZipFile(apkWithAssets.get().toString()); + apkZip + .stream() + .filter(entry -> entry.getName().startsWith("assets/")) + .forEach( + entry -> { + try { + zip.addEntry( + entry, + ByteStreams.toByteArray(apkZip.getInputStream(entry))); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + zip.addEntry("assets/", new byte[0], ZipEntry.STORED); + } else if (Files.exists(assetsRoot)) { ZipBuilderVisitorWithDirectories visitor = new ZipBuilderVisitorWithDirectories(zip, assetsRoot, "assets"); visitor.setCompress(compress); @@ -150,7 +189,7 @@ public class ResourcesZip { packages, rTxt, classJar, manifest, proguardMapping, resourcesRoot, logFile) .shrink(workingDirectory); return ShrunkResources.of( - new ResourcesZip(workingDirectory, assetsRoot, ids), + new ResourcesZip(workingDirectory, assetsRoot, ids, Optional.empty()), new UnvalidatedAndroidData( ImmutableList.of(workingDirectory), ImmutableList.of(assetsRoot), manifest)); } diff --git a/src/tools/android/java/com/google/devtools/build/android/aapt2/PackagedResources.java b/src/tools/android/java/com/google/devtools/build/android/aapt2/PackagedResources.java index 6f77b5966e..faad2cd868 100644 --- a/src/tools/android/java/com/google/devtools/build/android/aapt2/PackagedResources.java +++ b/src/tools/android/java/com/google/devtools/build/android/aapt2/PackagedResources.java @@ -119,7 +119,11 @@ public class PackagedResources { return of(apk, rTxt, proguardConfig, mainDexProguard, sourceJarPath, resourceIds); } - public Path resourceIds() { + public Path getResourceIds() { return resourceIds; } + + public Path getApk() { + return apk; + } } diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java index 6e1fba18c7..b912cc141e 100644 --- a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java +++ b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java @@ -17,6 +17,7 @@ import com.android.aapt.Resources.Plural; import com.android.aapt.Resources.Value; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; +import com.google.common.xml.XmlEscapers; import com.google.devtools.build.android.AndroidDataWritingVisitor; import com.google.devtools.build.android.AndroidDataWritingVisitor.ValuesResourceDefinition; import com.google.devtools.build.android.AndroidResourceSymbolSink; @@ -143,13 +144,10 @@ public class PluralXmlResourceValue implements XmlResourceValue { for (Plural.Entry entry : plural.getEntryList()) { String name = entry.getArity().toString().toLowerCase(); String value = - entry - .getItem() - .getStr() - .toString() - .replace("value: \"", "") - .replace("\"", "") - .replace('\n', ' '); + XmlEscapers.xmlContentEscaper().escape( + entry.getItem() + .getStr() + .getValue()); items.put(name, value); } diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java index 4006d4d7a4..9b9285621a 100644 --- a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java +++ b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java @@ -20,6 +20,7 @@ import com.android.aapt.Resources.Value; import com.android.resources.ResourceType; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; +import com.google.common.xml.XmlEscapers; import com.google.devtools.build.android.AndroidDataWritingVisitor; import com.google.devtools.build.android.AndroidDataWritingVisitor.StartTag; import com.google.devtools.build.android.AndroidResourceSymbolSink; @@ -236,7 +237,7 @@ public class SimpleXmlResourceValue implements XmlResourceValue { String stringValue = null; if (item.hasStr()) { - stringValue = item.getStr().toString(); + stringValue = XmlEscapers.xmlContentEscaper().escape(item.getStr().getValue()); } else if (item.hasRef()) { stringValue = "@" + item.getRef().getName(); } else if (item.hasStyledStr()) { diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java index 55c3d00fdd..0f6369d68b 100644 --- a/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java +++ b/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java @@ -86,6 +86,10 @@ public class StyleXmlResourceValue implements XmlResourceValue { if (style.hasParent()) { parent = proto.getCompoundValue().getStyle().getParent().getName(); + if (parent.startsWith("style/")) { + //Aapt2 compile breaks when style parent references are prepended with 'style/' + parent = parent.substring(6); + } } Map<String, String> items = itemMapFromProto(style); |