Track styleable and attr accurately in optimized shrinking
Instantiate the resource model including styleables
Ignore the resource model returned unused resources and explicitly only keep those that are reachable
Bug: b/319802261
Change-Id: I08d995c8e7715bdf3281667253021eebd94d109b
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 2dbcf84..ab97ce2 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
@@ -131,12 +131,13 @@
R8ResourceShrinkerModel model = new R8ResourceShrinkerModel(NoDebugReporter.INSTANCE, true);
for (PathAndBytes pathAndBytes : resourceTables.keySet()) {
ResourceTable loadedResourceTable = ResourceTable.parseFrom(pathAndBytes.bytes);
- model.instantiateFromResourceTable(loadedResourceTable);
+ model.instantiateFromResourceTable(loadedResourceTable, false);
}
- return shrinkModel(model);
+ return shrinkModel(model, false);
}
- public ShrinkerResult shrinkModel(R8ResourceShrinkerModel model) throws IOException {
+ public ShrinkerResult shrinkModel(
+ R8ResourceShrinkerModel model, boolean exactMatchingOfStyleablesAndAttr) throws IOException {
if (proguardMapStrings != null) {
new ProguardMappingsRecorder(proguardMapStrings).recordObfuscationMappings(model);
proguardMapStrings = null;
@@ -193,7 +194,7 @@
}
}
List<Integer> resourceIdsToRemove =
- unusedResources.stream().map(resource -> resource.value).collect(Collectors.toList());
+ getResourceIdsToRemove(unusedResources, model, exactMatchingOfStyleablesAndAttr);
Map<FeatureSplit, ResourceTable> shrunkenTables = new HashMap<>();
for (Entry<PathAndBytes, FeatureSplit> entry : resourceTables.entrySet()) {
ResourceTable shrunkenResourceTable =
@@ -204,6 +205,19 @@
return new ShrinkerResult(resEntriesToKeep.build(), shrunkenTables);
}
+ private static List<Integer> getResourceIdsToRemove(
+ List<Resource> unusedResources,
+ R8ResourceShrinkerModel model,
+ boolean exactMatchingOfStyleablesAndAttr) {
+ if (!exactMatchingOfStyleablesAndAttr) {
+ return unusedResources.stream().map(resource -> resource.value).collect(Collectors.toList());
+ }
+ return model.getResourceStore().getResources().stream()
+ .filter(r -> !r.isReachable())
+ .map(r -> r.value)
+ .collect(Collectors.toList());
+ }
+
// Lifted from com/android/utils/XmlUtils.java which we can't easily update internal dependency
// for.
/**
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 e0cca4f..088547e 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/R8ResourceShrinkerState.java
@@ -36,7 +36,7 @@
public void setResourceTableInput(InputStream inputStream) {
r8ResourceShrinkerModel = new R8ResourceShrinkerModel(NoDebugReporter.INSTANCE, true);
- r8ResourceShrinkerModel.instantiateFromResourceTable(inputStream);
+ r8ResourceShrinkerModel.instantiateFromResourceTable(inputStream, true);
}
public R8ResourceShrinkerModel getR8ResourceShrinkerModel() {
@@ -56,16 +56,16 @@
}
// Similar to instantiation in ProtoResourceTableGatherer, but using an inputstream.
- void instantiateFromResourceTable(InputStream inputStream) {
+ void instantiateFromResourceTable(InputStream inputStream, boolean includeStyleables) {
try {
ResourceTable resourceTable = ResourceTable.parseFrom(inputStream);
- instantiateFromResourceTable(resourceTable);
+ instantiateFromResourceTable(resourceTable, includeStyleables);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
- void instantiateFromResourceTable(ResourceTable resourceTable) {
+ void instantiateFromResourceTable(ResourceTable resourceTable, boolean includeStyleables) {
ResourceTableUtilKt.entriesSequence(resourceTable)
.iterator()
.forEachRemaining(
@@ -74,7 +74,7 @@
Entry entry = entryWrapper.getEntry();
int entryId = entryWrapper.getId();
recordSingleValueResources(resourceType, entry, entryId);
- if (resourceType != ResourceType.STYLEABLE) {
+ if (resourceType != ResourceType.STYLEABLE || includeStyleables) {
this.addResource(
resourceType,
entryWrapper.getPackageName(),