Add API and change default for missing library API modeling.

Bug: b/231547906
Change-Id: Iafc7031557535bc5af6cfa53b3d2b48006a1ab85
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index c158fc8..1495071 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -92,6 +92,7 @@
     private boolean minimalMainDex = false;
     private boolean skipDump = false;
     private final List<ProguardConfigurationSource> mainDexRules = new ArrayList<>();
+    private boolean enableMissingLibraryApiModeling = false;
 
     private Builder() {
       this(new DefaultD8DiagnosticsHandler());
@@ -322,6 +323,18 @@
       return self();
     }
 
+    /**
+     * Enable experimental/pre-release support for modeling missing library APIs.
+     *
+     * <p>This allows enabling the feature while it is still default disabled by the compiler. Once
+     * the feature is default enabled, calling this method will have no affect.
+     */
+    @Deprecated
+    public Builder setEnableExperimentalMissingLibraryApiModeling(boolean enable) {
+      this.enableMissingLibraryApiModeling = enable;
+      return self();
+    }
+
     @Override
     void validate() {
       if (isPrintHelp()) {
@@ -411,6 +424,7 @@
           getDumpInputFlags(),
           getMapIdProvider(),
           proguardMapConsumer,
+          enableMissingLibraryApiModeling,
           factory);
     }
   }
@@ -426,6 +440,7 @@
   private final boolean minimalMainDex;
   private final ImmutableList<ProguardConfigurationRule> mainDexKeepRules;
   private final StringConsumer proguardMapConsumer;
+  private final boolean enableMissingLibraryApiModeling;
   private final DexItemFactory factory;
 
   public static Builder builder() {
@@ -500,6 +515,7 @@
       DumpInputFlags dumpInputFlags,
       MapIdProvider mapIdProvider,
       StringConsumer proguardMapConsumer,
+      boolean enableMissingLibraryApiModeling,
       DexItemFactory factory) {
     super(
         inputApp,
@@ -529,6 +545,7 @@
     this.minimalMainDex = minimalMainDex;
     this.mainDexKeepRules = mainDexKeepRules;
     this.proguardMapConsumer = proguardMapConsumer;
+    this.enableMissingLibraryApiModeling = enableMissingLibraryApiModeling;
     this.factory = factory;
   }
 
@@ -545,6 +562,7 @@
     minimalMainDex = false;
     mainDexKeepRules = null;
     proguardMapConsumer = null;
+    enableMissingLibraryApiModeling = false;
     factory = null;
   }
 
@@ -602,6 +620,11 @@
     internal.synthesizedClassPrefix = synthesizedClassPrefix;
     internal.desugaredLibraryKeepRuleConsumer = desugaredLibraryKeepRuleConsumer;
 
+    if (!enableMissingLibraryApiModeling) {
+      internal.apiModelingOptions().disableApiCallerIdentification();
+      internal.apiModelingOptions().disableMissingApiModeling();
+    }
+
     // Default is to remove all javac generated assertion code when generating dex.
     assert internal.assertionsConfiguration == null;
     internal.assertionsConfiguration =
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 6c8f251..2b50253 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -213,6 +213,8 @@
 
     // Disable global optimizations.
     internal.disableGlobalOptimizations();
+    internal.apiModelingOptions().disableApiCallerIdentification();
+    internal.apiModelingOptions().disableMissingApiModeling();
 
     internal.setDumpInputFlags(getDumpInputFlags(), false);
     internal.dumpOptions = dumpOptions();
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 4e3e190..4e7ca32 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -114,6 +114,7 @@
     private final List<FeatureSplit> featureSplits = new ArrayList<>();
     private String synthesizedClassPrefix = "";
     private boolean skipDump = false;
+    private boolean enableMissingLibraryApiModeling = false;
 
     private boolean allowTestProguardOptions =
         System.getProperty("com.android.tools.r8.allowTestProguardOptions") != null;
@@ -431,6 +432,18 @@
       return self();
     }
 
+    /**
+     * Enable experimental/pre-release support for modeling missing library APIs.
+     *
+     * <p>This allows enabling the feature while it is still default disabled by the compiler. Once
+     * the feature is default enabled, calling this method will have no affect.
+     */
+    @Deprecated
+    public Builder setEnableExperimentalMissingLibraryApiModeling(boolean enable) {
+      this.enableMissingLibraryApiModeling = enable;
+      return self();
+    }
+
     @Override
     protected InternalProgramOutputPathConsumer createProgramOutputConsumer(
         Path path,
@@ -619,7 +632,8 @@
               getThreadCount(),
               getDumpInputFlags(),
               getMapIdProvider(),
-              getSourceFileProvider());
+              getSourceFileProvider(),
+              enableMissingLibraryApiModeling);
 
       if (inputDependencyGraphConsumer != null) {
         inputDependencyGraphConsumer.finished();
@@ -704,6 +718,7 @@
   private final FeatureSplitConfiguration featureSplitConfiguration;
   private final String synthesizedClassPrefix;
   private final boolean skipDump;
+  private final boolean enableMissingLibraryApiModeling;
 
   /** Get a new {@link R8Command.Builder}. */
   public static Builder builder() {
@@ -792,7 +807,8 @@
       int threadCount,
       DumpInputFlags dumpInputFlags,
       MapIdProvider mapIdProvider,
-      SourceFileProvider sourceFileProvider) {
+      SourceFileProvider sourceFileProvider,
+      boolean enableMissingLibraryApiModeling) {
     super(
         inputApp,
         mode,
@@ -831,6 +847,7 @@
     this.featureSplitConfiguration = featureSplitConfiguration;
     this.synthesizedClassPrefix = synthesizedClassPrefix;
     this.skipDump = skipDump;
+    this.enableMissingLibraryApiModeling = enableMissingLibraryApiModeling;
   }
 
   private R8Command(boolean printHelp, boolean printVersion) {
@@ -854,6 +871,7 @@
     featureSplitConfiguration = null;
     synthesizedClassPrefix = null;
     skipDump = false;
+    enableMissingLibraryApiModeling = false;
   }
 
   public DexItemFactory getDexItemFactory() {
@@ -960,6 +978,10 @@
 
     internal.outputInspections = InspectorImpl.wrapInspections(getOutputInspections());
 
+    if (!enableMissingLibraryApiModeling) {
+      internal.apiModelingOptions().disableMissingApiModeling();
+    }
+
     // Default is to remove all javac generated assertion code when generating dex.
     assert internal.assertionsConfiguration == null;
     AssertionsConfiguration.Builder builder = AssertionsConfiguration.builder(getReporter());
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 48ac2b9..b44c067 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -256,7 +256,6 @@
     enableInitializedClassesAnalysis = false;
     callSiteOptimizationOptions.disableOptimization();
     horizontalClassMergerOptions.setRestrictToSynthetics();
-    apiModelTestingOptions.disableApiCallerIdentification();
   }
 
   public boolean printTimes = System.getProperty("com.android.tools.r8.printtimes") != null;
@@ -1669,6 +1668,15 @@
           });
     }
 
+    /**
+     * Disable the workarounds for missing APIs. This does not disable the use of the database, just
+     * the introduction of soft-verification workarounds for potentially missing API references.
+     */
+    public void disableMissingApiModeling() {
+      enableOutliningOfMethods = false;
+      enableStubbingOfClasses = false;
+    }
+
     public void disableApiCallerIdentification() {
       enableApiCallerIdentification = false;
     }