Add resource logging api, and report resource logs

The current implementation is consistent with the old resource shrinker for legacy mode

Bug: b/360284025
Bug: b/360284664
Change-Id: Idfce812bc92f357c04e2b5944d5db43253fd970a
Fixes: 360284025
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 7a82e3f..f1ba15e 100644
--- a/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
+++ b/src/resourceshrinker/java/com/android/build/shrinker/r8integration/LegacyResourceShrinker.java
@@ -10,9 +10,9 @@
 
 import com.android.aapt.Resources.ResourceTable;
 import com.android.aapt.Resources.XmlNode;
-import com.android.build.shrinker.NoDebugReporter;
 import com.android.build.shrinker.ResourceShrinkerImplKt;
 import com.android.build.shrinker.ResourceTableUtilKt;
+import com.android.build.shrinker.ShrinkerDebugReporter;
 import com.android.build.shrinker.graph.ProtoResourcesGraphBuilder;
 import com.android.build.shrinker.obfuscation.ProguardMappingsRecorder;
 import com.android.build.shrinker.r8integration.R8ResourceShrinkerState.R8ResourceShrinkerModel;
@@ -53,6 +53,7 @@
   private final Collection<PathAndBytes> resFolderInputs;
   private final Collection<PathAndBytes> xmlInputs;
   private List<String> proguardMapStrings;
+  private final ShrinkerDebugReporter debugReporter;
   private final List<PathAndBytes> manifest;
   private final Map<PathAndBytes, FeatureSplit> resourceTables;
 
@@ -65,6 +66,7 @@
     private final List<PathAndBytes> manifests = new ArrayList<>();
     private final Map<PathAndBytes, FeatureSplit> resourceTables = new HashMap<>();
     private List<String> proguardMapStrings;
+    private ShrinkerDebugReporter debugReporter;
 
     private Builder() {}
 
@@ -117,12 +119,18 @@
           manifests,
           resourceTables,
           xmlInputs.values(),
-          proguardMapStrings);
+          proguardMapStrings,
+          debugReporter);
     }
 
     public void setProguardMapStrings(List<String> proguardMapStrings) {
       this.proguardMapStrings = proguardMapStrings;
     }
+
+    public Builder setShrinkerDebugReporter(ShrinkerDebugReporter debugReporter) {
+      this.debugReporter = debugReporter;
+      return this;
+    }
   }
 
   private LegacyResourceShrinker(
@@ -131,13 +139,15 @@
       List<PathAndBytes> manifests,
       Map<PathAndBytes, FeatureSplit> resourceTables,
       Collection<PathAndBytes> xmlInputs,
-      List<String> proguardMapStrings) {
+      List<String> proguardMapStrings,
+      ShrinkerDebugReporter debugReporter) {
     this.dexInputs = dexInputs;
     this.resFolderInputs = resFolderInputs;
     this.manifest = manifests;
     this.resourceTables = resourceTables;
     this.xmlInputs = xmlInputs;
     this.proguardMapStrings = proguardMapStrings;
+    this.debugReporter = debugReporter;
   }
 
   public static Builder builder() {
@@ -145,7 +155,7 @@
   }
 
   public ShrinkerResult run() throws IOException, ParserConfigurationException, SAXException {
-    R8ResourceShrinkerModel model = new R8ResourceShrinkerModel(NoDebugReporter.INSTANCE, true);
+    R8ResourceShrinkerModel model = new R8ResourceShrinkerModel(debugReporter, true);
     for (PathAndBytes pathAndBytes : resourceTables.keySet()) {
       ResourceTable loadedResourceTable = ResourceTable.parseFrom(pathAndBytes.bytes);
       model.instantiateFromResourceTable(loadedResourceTable, false);
@@ -156,7 +166,7 @@
     }
     for (Entry<String, byte[]> entry : dexInputs.entrySet()) {
       // The analysis needs an origin for the dex files, synthesize an easy recognizable one.
-      Path inMemoryR8 = Paths.get("in_memory_r8_" + entry.getKey() + ".dex");
+      Path inMemoryR8 = Paths.get("in_memory_r8_" + entry.getKey());
       R8ResourceShrinker.runResourceShrinkerAnalysis(
           entry.getValue(), inMemoryR8, new DexFileAnalysisCallback(inMemoryR8, model));
     }
@@ -188,11 +198,19 @@
     ResourceStore resourceStore = model.getResourceStore();
     resourceStore.processToolsAttributes();
     model.keepPossiblyReferencedResources();
+    debugReporter.debug(model.getResourceStore()::dumpResourceModel);
     // Transitively mark the reachable resources in the model.
     // Finds unused resources in provided resources collection.
     // Marks all used resources as 'reachable' in original collection.
     List<Resource> unusedResources =
-        ResourcesUtil.findUnusedResources(model.getResourceStore().getResources(), x -> {});
+        ResourcesUtil.findUnusedResources(
+            model.getResourceStore().getResources(),
+            roots -> {
+              debugReporter.debug(() -> "The root reachable resources are:");
+              roots.forEach(root -> debugReporter.debug(() -> " " + root));
+            });
+    debugReporter.debug(() -> "Unused resources are: ");
+    unusedResources.forEach(unused -> debugReporter.debug(() -> " " + unused));
     ImmutableSet.Builder<String> resEntriesToKeep = new ImmutableSet.Builder<>();
     for (PathAndBytes xmlInput : Iterables.concat(xmlInputs, resFolderInputs)) {
       if (ResourceShrinkerImplKt.isJarPathReachable(resourceStore, xmlInput.path.toString())) {