Support adding additional raw xml files to R8 resource shrinking
To ensure that we can parse all xml keep rules we introduce a new Kind for passing in rules. Rules are explicitly not output again, and only used for extracting keep rules.
This will ensure that we are compatible with the old resource shrinker
and additionally the setup can ensure that we will not hit cases where
aapt have removed duplicates (AGP can pass all files from the
individual res folders, even when there are name clashes)
Bug: b/287398085
Change-Id: I167c75e3b244d96870524e8a67141a22dd463d68
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
index f1ba15e..019a123 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
@@ -52,6 +52,7 @@
private final Map<String, byte[]> dexInputs;
private final Collection<PathAndBytes> resFolderInputs;
private final Collection<PathAndBytes> xmlInputs;
+ private final List<byte[]> keepRuleInput;
private List<String> proguardMapStrings;
private final ShrinkerDebugReporter debugReporter;
private final List<PathAndBytes> manifest;
@@ -62,6 +63,7 @@
private final Map<String, byte[]> dexInputs = new HashMap<>();
private final Map<Path, PathAndBytes> resFolderInputs = new HashMap<>();
private final Map<Path, PathAndBytes> xmlInputs = new HashMap<>();
+ private final List<byte[]> keepRuleInput = new ArrayList<>();
private final List<PathAndBytes> manifests = new ArrayList<>();
private final Map<PathAndBytes, FeatureSplit> resourceTables = new HashMap<>();
@@ -91,6 +93,11 @@
return this;
}
+ public Builder addKeepRuleInput(byte[] bytes) {
+ keepRuleInput.add(bytes);
+ return this;
+ }
+
public Builder addResFolderInput(Path path, byte[] bytes) {
PathAndBytes existing = resFolderInputs.get(path);
if (existing != null) {
@@ -119,6 +126,7 @@
manifests,
resourceTables,
xmlInputs.values(),
+ keepRuleInput,
proguardMapStrings,
debugReporter);
}
@@ -139,6 +147,7 @@
List<PathAndBytes> manifests,
Map<PathAndBytes, FeatureSplit> resourceTables,
Collection<PathAndBytes> xmlInputs,
+ List<byte[]> additionalRawXmlInputs,
List<String> proguardMapStrings,
ShrinkerDebugReporter debugReporter) {
this.dexInputs = dexInputs;
@@ -146,6 +155,7 @@
this.manifest = manifests;
this.resourceTables = resourceTables;
this.xmlInputs = xmlInputs;
+ this.keepRuleInput = additionalRawXmlInputs;
this.proguardMapStrings = proguardMapStrings;
this.debugReporter = debugReporter;
}
@@ -174,10 +184,8 @@
ProtoAndroidManifestUsageRecorderKt.recordUsagesFromNode(
XmlNode.parseFrom(pathAndBytes.bytes), model);
}
- for (PathAndBytes xmlInput : xmlInputs) {
- if (xmlInput.path.startsWith("res/raw")) {
- ToolsAttributeUsageRecorderKt.processRawXml(getUtfReader(xmlInput.getBytes()), model);
- }
+ for (byte[] keepBytes : keepRuleInput) {
+ ToolsAttributeUsageRecorderKt.processRawXml(getUtfReader(keepBytes), model);
}
ImmutableMap<String, PathAndBytes> resFolderMappings =
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
index 2dd02e8..5ac9755 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
@@ -53,6 +53,7 @@
private final Function<Exception, RuntimeException> errorHandler;
private final R8ResourceShrinkerModel r8ResourceShrinkerModel;
private final Map<String, Supplier<InputStream>> xmlFileProviders = new HashMap<>();
+ private final List<Supplier<InputStream>> keepRuleFileProviders = new ArrayList<>();
private final List<Supplier<InputStream>> manifestProviders = new ArrayList<>();
private final Map<String, Supplier<InputStream>> resfileProviders = new HashMap<>();
@@ -141,6 +142,10 @@
this.xmlFileProviders.put(location, inputStreamSupplier);
}
+ public void addKeepRuleRileProvider(Supplier<InputStream> inputStreamSupplier) {
+ this.keepRuleFileProviders.add(inputStreamSupplier);
+ }
+
public void addResFileProvider(Supplier<InputStream> inputStreamSupplier, String location) {
this.resfileProviders.put(location, inputStreamSupplier);
}
@@ -308,11 +313,9 @@
}
public void updateModelWithKeepXmlReferences() throws IOException {
- for (Map.Entry<String, Supplier<InputStream>> entry : xmlFileProviders.entrySet()) {
- if (entry.getKey().startsWith("res/raw")) {
- ToolsAttributeUsageRecorderKt.processRawXml(
- getUtfReader(entry.getValue().get().readAllBytes()), r8ResourceShrinkerModel);
- }
+ for (Supplier<InputStream> keepRuleFileProvider : keepRuleFileProviders) {
+ ToolsAttributeUsageRecorderKt.processRawXml(
+ getUtfReader(keepRuleFileProvider.get().readAllBytes()), r8ResourceShrinkerModel);
}
}