Reland support for resource shrinking in dumps

Use the reflective based lookup of builder methods to support older
versions with dump runner

Change-Id: Id6fbe3b9aba74e2c73c68d1659fb7437d74ad021
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java b/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
index f6c7269..a5aadef 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpBase.java
@@ -34,6 +34,22 @@
         .accept(new Object[] {isolatedSplits});
   }
 
+  static void setupResourceShrinking(
+      Path androidResourcesInput, Path androidResourcesOutput, Object builder) {
+    try {
+      Class<?> androidResourceProvider =
+          Class.forName("com.android.tools.r8.AndroidResourceProvider");
+      Class<?> androidResourceConsumer =
+          Class.forName("com.android.tools.r8.AndroidResourceConsumer");
+      getReflectiveBuilderMethod(builder, "setAndroidResourceProvider", androidResourceProvider)
+          .accept(new Object[] {createAndroidResourceProvider(androidResourcesInput)});
+      getReflectiveBuilderMethod(builder, "setAndroidResourceConsumer", androidResourceConsumer)
+          .accept(new Object[] {createAndroidResourceConsumer(androidResourcesOutput)});
+    } catch (ClassNotFoundException e) {
+      // Ignore
+    }
+  }
+
   static void addArtProfilesForRewriting(Object builder, Map<Path, Path> artProfileFiles) {
     try {
       Class<?> artProfileProviderClass =
@@ -62,38 +78,44 @@
         .accept(new Object[] {createStartupProfileProviders(startupProfileFiles)});
   }
 
-  static Object createArtProfileProvider(Path artProfile) {
-    Object[] artProfileProvider = new Object[1];
+  static Object callReflectiveDumpUtilsMethodWithPath(Path path, String method) {
+    Object[] returnObject = new Object[1];
     boolean found =
         callReflectiveUtilsMethod(
-            "createArtProfileProviderFromDumpFile",
+            method,
             new Class<?>[] {Path.class},
-            fn -> artProfileProvider[0] = fn.apply(new Object[] {artProfile}));
+            fn -> returnObject[0] = fn.apply(new Object[] {path}));
     if (!found) {
       System.out.println(
-          "Unable to add art profiles as input. "
-              + "Method createArtProfileProviderFromDumpFile() was not found.");
+          "Unable to call invoke method on path "
+              + path
+              + ". "
+              + "Method "
+              + method
+              + "() was not found.");
       return null;
     }
-    System.out.println(artProfileProvider[0]);
-    return artProfileProvider[0];
+    return returnObject[0];
+  }
+
+  static Object createAndroidResourceProvider(Path resourceInput) {
+    return callReflectiveDumpUtilsMethodWithPath(
+        resourceInput, "createAndroidResourceProviderFromDumpFile");
+  }
+
+  static Object createAndroidResourceConsumer(Path resourceOutput) {
+    return callReflectiveDumpUtilsMethodWithPath(
+        resourceOutput, "createAndroidResourceConsumerFromDumpFile");
+  }
+
+  static Object createArtProfileProvider(Path artProfile) {
+    return callReflectiveDumpUtilsMethodWithPath(
+        artProfile, "createArtProfileProviderFromDumpFile");
   }
 
   static Object createResidualArtProfileConsumer(Path residualArtProfile) {
-    Object[] residualArtProfileConsumer = new Object[1];
-    boolean found =
-        callReflectiveUtilsMethod(
-            "createResidualArtProfileConsumerFromDumpFile",
-            new Class<?>[] {Path.class},
-            fn -> residualArtProfileConsumer[0] = fn.apply(new Object[] {residualArtProfile}));
-    if (!found) {
-      System.out.println(
-          "Unable to add art profiles as input. "
-              + "Method createResidualArtProfileConsumerFromDumpFile() was not found.");
-      return null;
-    }
-    System.out.println(residualArtProfileConsumer[0]);
-    return residualArtProfileConsumer[0];
+    return callReflectiveDumpUtilsMethodWithPath(
+        residualArtProfile, "createResidualArtProfileConsumerFromDumpFile");
   }
 
   static Collection<Object> createStartupProfileProviders(List<Path> startupProfileFiles) {
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
index cd01544..9112b77 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java
@@ -64,7 +64,7 @@
           "--startup-profile");
 
   private static final List<String> VALID_OPTIONS_WITH_TWO_OPERANDS =
-      Arrays.asList("--art-profile", "--feature-jar");
+      Arrays.asList("--art-profile", "--feature-jar", "--android-resources");
 
   private static boolean FileUtils_isArchive(Path path) {
     String name = path.getFileName().toString().toLowerCase(Locale.ROOT);
@@ -91,6 +91,8 @@
     List<Path> mainDexRulesFiles = new ArrayList<>();
     Map<Path, Path> artProfileFiles = new LinkedHashMap<>();
     List<Path> startupProfileFiles = new ArrayList<>();
+    Path androidResourcesInput = null;
+    Path androidResourcesOutput = null;
     int minApi = 1;
     int threads = -1;
     boolean enableMissingLibraryApiModeling = false;
@@ -202,6 +204,12 @@
               artProfileFiles.put(Paths.get(firstOperand), Paths.get(secondOperand));
               break;
             }
+          case "--android-resources":
+            {
+              androidResourcesInput = Paths.get(firstOperand);
+              androidResourcesOutput = Paths.get(secondOperand);
+              break;
+            }
           case "--feature-jar":
             {
               Path featureIn = Paths.get(firstOperand);
@@ -237,6 +245,9 @@
     if (desugaredLibJson != null) {
       commandBuilder.addDesugaredLibraryConfiguration(readAllBytesJava7(desugaredLibJson));
     }
+    if (androidResourcesInput != null) {
+      setupResourceShrinking(androidResourcesInput, androidResourcesOutput, commandBuilder);
+    }
     if (desugaredLibKeepRuleConsumer != null) {
       commandBuilder.setDesugaredLibraryKeepRuleConsumer(desugaredLibKeepRuleConsumer);
     }
diff --git a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java b/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
index 4356671..ef013f6 100644
--- a/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/CompileDumpUtils.java
@@ -4,6 +4,10 @@
 
 package com.android.tools.r8.utils;
 
+import com.android.tools.r8.AndroidResourceConsumer;
+import com.android.tools.r8.AndroidResourceProvider;
+import com.android.tools.r8.ArchiveProtoAndroidResourceConsumer;
+import com.android.tools.r8.ArchiveProtoAndroidResourceProvider;
 import com.android.tools.r8.KeepMethodForCompileDump;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
@@ -34,6 +38,16 @@
   }
 
   @KeepMethodForCompileDump
+  static AndroidResourceProvider createAndroidResourceProviderFromDumpFile(Path resourceInput) {
+    return new ArchiveProtoAndroidResourceProvider(resourceInput);
+  }
+
+  @KeepMethodForCompileDump
+  static AndroidResourceConsumer createAndroidResourceConsumerFromDumpFile(Path resourceOutput) {
+    return new ArchiveProtoAndroidResourceConsumer(resourceOutput);
+  }
+
+  @KeepMethodForCompileDump
   static StartupProfileProvider createStartupProfileProviderFromDumpFile(Path path) {
     return new StartupProfileProvider() {
 
diff --git a/tools/compiledump.py b/tools/compiledump.py
index 3c483f7..c819865 100755
--- a/tools/compiledump.py
+++ b/tools/compiledump.py
@@ -223,6 +223,9 @@
     def main_dex_rules_resource(self):
         return self.if_exists('main-dex-rules.txt')
 
+    def resource_ap_file(self):
+        return self.if_exists('app-res.ap_')
+
     def art_profile_resources(self):
         art_profile_resources = []
         while True:
@@ -633,6 +636,10 @@
             cmd.append('--isolated-splits')
         if dump.library_jar():
             cmd.extend(['--lib', dump.library_jar()])
+        if dump.resource_ap_file():
+            res_output = os.path.join(temp, 'ap-res-out.ap_')
+            cmd.extend(['--android-resources', dump.resource_ap_file(),
+                        res_output])
         if dump.classpath_jar() and not is_l8_compiler(compiler):
             cmd.extend([
                 '--target' if compiler == 'tracereferences' else '--classpath',