Add Android.jar path parameter to file generation tools

Bug: b/274414020
Change-Id: I4be0fa742c52e95b226d308ac88a9cd8c085b67e
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
index 4a43131..9c46517d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/AbstractGenerateFiles.java
@@ -28,8 +28,6 @@
 
 public abstract class AbstractGenerateFiles {
 
-  private static final String ANDROID_JAR_PATTERN = "third_party/android_jar/lib-v%d/android.jar";
-
   // If we increment this api level, we need to verify everything works correctly.
   static final AndroidApiLevel MAX_TESTED_ANDROID_API_LEVEL = AndroidApiLevel.U;
 
@@ -41,26 +39,33 @@
   final Path desugaredLibrarySpecificationPath;
   final Collection<Path> desugaredLibraryImplementation;
   final Path outputDirectory;
+  final Path androidJar;
 
-  public AbstractGenerateFiles(
-      String desugarConfigurationPath, String desugarImplementationPath, String outputDirectory)
+  AbstractGenerateFiles(
+      String desugarConfigurationPath,
+      String desugarImplementationPath,
+      String outputDirectory,
+      String androidJarPath)
       throws Exception {
     this(
         Paths.get(desugarConfigurationPath),
         ImmutableList.of(Paths.get(desugarImplementationPath)),
-        Paths.get(outputDirectory));
+        Paths.get(outputDirectory),
+        Paths.get(androidJarPath));
   }
 
   AbstractGenerateFiles(
       Path desugarConfigurationPath,
       Collection<Path> desugarImplementationPath,
-      Path outputDirectory)
+      Path outputDirectory,
+      Path androidJar)
       throws Exception {
+    assert androidJar != null;
     this.desugaredLibrarySpecificationPath = desugarConfigurationPath;
     DesugaredLibrarySpecification specification =
         readDesugaredLibraryConfiguration(desugarConfigurationPath);
-    Path androidJarPath = getAndroidJarPath(specification.getRequiredCompilationApiLevel());
-    DexApplication app = createApp(androidJarPath, options);
+    this.androidJar = androidJar;
+    DexApplication app = createApp(androidJar, options);
     this.desugaredLibrarySpecification = specification.toMachineSpecification(app, Timing.empty());
     this.desugaredLibraryImplementation = desugarImplementationPath;
     this.outputDirectory = outputDirectory;
@@ -69,15 +74,6 @@
     }
   }
 
-  static Path getAndroidJarPath(AndroidApiLevel apiLevel) {
-    String jar =
-        apiLevel == AndroidApiLevel.MASTER
-            ? "third_party/android_jar/lib-master/android.jar"
-            : String.format(ANDROID_JAR_PATTERN, apiLevel.getLevel());
-    return Paths.get(jar);
-  }
-
-
   private DesugaredLibrarySpecification readDesugaredLibraryConfiguration(
       Path desugarConfigurationPath) {
     return DesugaredLibrarySpecificationParser.parseDesugaredLibrarySpecification(
@@ -88,10 +84,10 @@
         AndroidApiLevel.B.getLevel());
   }
 
-  private static DexApplication createApp(Path androidLib, InternalOptions options)
+  private static DexApplication createApp(Path androidJar, InternalOptions options)
       throws IOException {
     AndroidApp.Builder builder = AndroidApp.builder();
-    AndroidApp inputApp = builder.addLibraryFiles(androidLib).build();
+    AndroidApp inputApp = builder.addLibraryFiles(androidJar).build();
     ApplicationReader applicationReader = new ApplicationReader(inputApp, options, Timing.empty());
     ExecutorService executorService = ThreadUtils.getExecutorService(options);
     assert !options.ignoreJavaLibraryOverride;
@@ -103,19 +99,41 @@
 
   abstract AndroidApiLevel run() throws Exception;
 
-  public static void main(String[] args) throws Exception {
-    if (args.length == 3) {
-      new GenerateLintFiles(args[0], args[1], args[2]).run();
-      return;
+  private static String getFallBackAndroidJarPath(AndroidApiLevel apiLevel) {
+    String jar =
+        apiLevel == AndroidApiLevel.MASTER
+            ? "third_party/android_jar/lib-master/android.jar"
+            : String.format("third_party/android_jar/lib-v%d/android.jar", apiLevel.getLevel());
+    Path jarPath = Paths.get(jar);
+    if (!Files.exists(jarPath)) {
+      throw new RuntimeException(
+          "Generate files tools should pass a valid recent android.jar as parameter if used outside"
+              + " of the r8 repository. Missing file: "
+              + jarPath);
     }
-    if (args.length == 4 && args[0].equals("--generate-api-docs")) {
-      new GenerateHtmlDoc(args[1], args[2], args[3]).run();
+    return jar;
+  }
+
+  private static String getAndroidJarPath(String[] args, int fullLength) {
+    return args.length == fullLength
+        ? args[fullLength - 1]
+        : getFallBackAndroidJarPath(MAX_TESTED_ANDROID_API_LEVEL);
+  }
+
+  public static void main(String[] args) throws Exception {
+    if (args[0].equals("--generate-api-docs")) {
+      if (args.length == 4 || args.length == 5) {
+        new GenerateHtmlDoc(args[1], args[2], args[3], getAndroidJarPath(args, 5)).run();
+        return;
+      }
+    } else if (args.length == 3 || args.length == 4) {
+      new GenerateLintFiles(args[0], args[1], args[2], getAndroidJarPath(args, 4)).run();
       return;
     }
     throw new RuntimeException(
         StringUtils.joinLines(
             "Invalid invocation.",
-            "Usage: GenerateLineFiles [--generate-api-docs] "
-                + "<desugar configuration> <desugar implementation> <output directory>"));
+            "Usage: AbstractGenerateFiles [--generate-api-docs] <desugar configuration> <desugar"
+                + " implementation> <output directory> [<android jar path>]"));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
index c62d6b1..31ba7e1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateHtmlDoc.java
@@ -37,9 +37,12 @@
   private static final String SUP_4 = "<sup>4</sup>";
 
   public GenerateHtmlDoc(
-      String desugarConfigurationPath, String desugarImplementationPath, String outputDirectory)
+      String desugarConfigurationPath,
+      String desugarImplementationPath,
+      String outputDirectory,
+      String androidJarPath)
       throws Exception {
-    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory);
+    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory, androidJarPath);
   }
 
   private static class StringBuilderWithIndent {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
index 5bfbe46..4654124d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/GenerateLintFiles.java
@@ -55,22 +55,27 @@
   private static final boolean FORMAT_WITH_FIELD = true;
 
   public static GenerateLintFiles createForTesting(
-      Path specification, Set<Path> implementation, Path outputDirectory) throws Exception {
-    return new GenerateLintFiles(specification, implementation, outputDirectory);
-  }
-
-  public GenerateLintFiles(
-      String desugarConfigurationPath, String desugarImplementationPath, String outputDirectory)
+      Path specification, Set<Path> implementation, Path outputDirectory, Path androidJar)
       throws Exception {
-    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory);
+    return new GenerateLintFiles(specification, implementation, outputDirectory, androidJar);
   }
 
   public GenerateLintFiles(
+      String desugarConfigurationPath,
+      String desugarImplementationPath,
+      String outputDirectory,
+      String androidJarPath)
+      throws Exception {
+    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory, androidJarPath);
+  }
+
+  private GenerateLintFiles(
       Path desugarConfigurationPath,
       Collection<Path> desugarImplementationPath,
-      Path outputDirectory)
+      Path outputDirectory,
+      Path androidJar)
       throws Exception {
-    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory);
+    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory, androidJar);
   }
 
   private CfCode buildEmptyThrowingCfCode(DexMethod method) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
index 2b5de3f..0ad53ed 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ExtractWrapperTypesTest.java
@@ -516,7 +516,8 @@
         GenerateLintFiles.createForTesting(
             libraryDesugaringSpecification.getSpecification(),
             libraryDesugaringSpecification.getDesugarJdkLibs(),
-            out);
+            out,
+            ToolHelper.getAndroidJar(AndroidApiLevel.U));
     AndroidApiLevel compileApi = desugaredApi.run();
     return new CodeInspector(
         out.resolve("compile_api_level_" + compileApi.getLevel())
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
index 446b84e..aeedca9 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/LintFilesTest.java
@@ -41,6 +41,8 @@
 @RunWith(Parameterized.class)
 public class LintFilesTest extends DesugaredLibraryTestBase {
 
+  private static final String ANDROID_JAR_34 = "third_party/android_jar/lib-v34/android.jar";
+
   private final LibraryDesugaringSpecification libraryDesugaringSpecification;
 
   private List<String> lintContents;
@@ -237,12 +239,19 @@
           spec == JDK8
               ? ToolHelper.DESUGARED_JDK_8_LIB_JAR
               : LibraryDesugaringSpecification.getTempLibraryJDK11Undesugar();
-      new GenerateHtmlDoc(spec.getSpecification().toString(), jdkLibJar.toString(), html.toString())
+      new GenerateHtmlDoc(
+              spec.getSpecification().toString(),
+              jdkLibJar.toString(),
+              html.toString(),
+              ANDROID_JAR_34)
           .run(spec + ".html");
       Path lint = top.resolve("lint_" + spec);
       Files.createDirectories(lint);
       new GenerateLintFiles(
-              spec.getSpecification().toString(), jdkLibJar.toString(), lint.toString())
+              spec.getSpecification().toString(),
+              jdkLibJar.toString(),
+              lint.toString(),
+              ANDROID_JAR_34)
           .run();
     }
   }