Inline string resource values into code
This will inline resource strings that have a single value into code if the Resources:getString(int id) method is used
This is currently only inlining into code, I will follow up with inlining into xml and then implement a second round of tracing to (hopefully) eliminate the resource table entry.
Bug: b/311321134
Bug: b/287398085
Change-Id: Id5f5301a13a3d0d3a17da8a539ba0a0c7dfe9297
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 8273c96..e0cca4f 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
@@ -4,7 +4,11 @@
package com.android.build.shrinker.r8integration;
+import com.android.aapt.Resources.ConfigValue;
+import com.android.aapt.Resources.Entry;
+import com.android.aapt.Resources.Item;
import com.android.aapt.Resources.ResourceTable;
+import com.android.aapt.Resources.Value;
import com.android.build.shrinker.NoDebugReporter;
import com.android.build.shrinker.ResourceShrinkerModel;
import com.android.build.shrinker.ResourceTableUtilKt;
@@ -16,7 +20,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class R8ResourceShrinkerState {
@@ -38,12 +44,17 @@
}
public static class R8ResourceShrinkerModel extends ResourceShrinkerModel {
+ private final Map<Integer, String> stringResourcesWithSingleValue = new HashMap<>();
public R8ResourceShrinkerModel(
ShrinkerDebugReporter debugReporter, boolean supportMultipackages) {
super(debugReporter, supportMultipackages);
}
+ public Map<Integer, String> getStringResourcesWithSingleValue() {
+ return stringResourcesWithSingleValue;
+ }
+
// Similar to instantiation in ProtoResourceTableGatherer, but using an inputstream.
void instantiateFromResourceTable(InputStream inputStream) {
try {
@@ -60,14 +71,34 @@
.forEachRemaining(
entryWrapper -> {
ResourceType resourceType = ResourceType.fromClassName(entryWrapper.getType());
+ Entry entry = entryWrapper.getEntry();
+ int entryId = entryWrapper.getId();
+ recordSingleValueResources(resourceType, entry, entryId);
if (resourceType != ResourceType.STYLEABLE) {
this.addResource(
resourceType,
entryWrapper.getPackageName(),
- ResourcesUtil.resourceNameToFieldName(entryWrapper.getEntry().getName()),
- entryWrapper.getId());
+ ResourcesUtil.resourceNameToFieldName(entry.getName()),
+ entryId);
}
});
}
+
+ private void recordSingleValueResources(ResourceType resourceType, Entry entry, int entryId) {
+ if (!entry.hasOverlayableItem() && entry.getConfigValueList().size() == 1) {
+ if (resourceType == ResourceType.STRING) {
+ ConfigValue configValue = entry.getConfigValue(0);
+ if (configValue.hasValue()) {
+ Value value = configValue.getValue();
+ if (value.hasItem()) {
+ Item item = value.getItem();
+ if (item.hasStr()) {
+ stringResourcesWithSingleValue.put(entryId, item.getStr().getValue());
+ }
+ }
+ }
+ }
+ }
+ }
}
}