Refine api checks for inlining

Bug: b/382017168
Change-Id: I7ad1878b76db1957e70d7837ab2afabe49c23086
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index fea6435..e811b72 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -156,7 +156,7 @@
       WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
     // Do not inline if the inlinee is greater than the api caller level.
     // TODO(b/188498051): We should not force inline lower api method calls.
-    if (!isApiSafeForInlining(method, singleTarget, options, whyAreYouNotInliningReporter)) {
+    if (!isApiSafeForInlining(method, singleTarget, appView, whyAreYouNotInliningReporter)) {
       return false;
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 8b213c7..e7fc8c5 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -988,7 +988,7 @@
       return null;
     }
     // Check the api level is allowed to be inlined.
-    if (!isApiSafeForInlining(method, singleTarget, appView.options())) {
+    if (!isApiSafeForInlining(method, singleTarget, appView)) {
       return null;
     }
     // Check that the entire constructor chain can be inlined into the current context.
@@ -1015,7 +1015,7 @@
         return null;
       }
       // Check the api level is allowed to be inlined.
-      if (!isApiSafeForInlining(method, encodedParent, appView.options())) {
+      if (!isApiSafeForInlining(method, encodedParent, appView)) {
         return null;
       }
       parent =
diff --git a/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java b/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
index 26b85ed..690724e 100644
--- a/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/singlecaller/SingleCallerScanner.java
@@ -49,7 +49,7 @@
         (callee, caller) ->
             callee.getDefinition().isLibraryMethodOverride().isPossiblyTrue()
                 || !appView.getKeepInfo(callee).isSingleCallerInliningAllowed(options, callee)
-                || !AndroidApiLevelUtils.isApiSafeForInlining(caller, callee, appView.options()));
+                || !AndroidApiLevelUtils.isApiSafeForInlining(caller, callee, appView));
     return traceInstructions(singleCallerMethodCandidates, executorService);
   }
 
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
index 8c483f7..cf855e7 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -34,30 +34,34 @@
 public class AndroidApiLevelUtils {
 
   public static boolean isApiSafeForInlining(
-      ProgramMethod caller, ProgramMethod inlinee, InternalOptions options) {
+      ProgramMethod caller,
+      ProgramMethod inlinee,
+      AppView<? extends AppInfoWithClassHierarchy> appView) {
     return isApiSafeForInlining(
-        caller, inlinee, options, NopWhyAreYouNotInliningReporter.getInstance());
+        caller, inlinee, appView, NopWhyAreYouNotInliningReporter.getInstance());
   }
 
-  @SuppressWarnings("ReferenceEquality")
   public static boolean isApiSafeForInlining(
       ProgramMethod caller,
       ProgramMethod inlinee,
-      InternalOptions options,
+      AppView<? extends AppInfoWithClassHierarchy> appView,
       WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
-    if (!options.apiModelingOptions().isApiCallerIdentificationEnabled()) {
+    if (!appView.options().apiModelingOptions().isApiCallerIdentificationEnabled()) {
       return true;
     }
-    if (caller.getHolderType() == inlinee.getHolderType()) {
+    if (caller.getHolder() == inlinee.getHolder()) {
       return true;
     }
     ComputedApiLevel callerApiLevelForCode = caller.getDefinition().getApiLevelForCode();
+    ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
     if (callerApiLevelForCode.isUnknownApiLevel()) {
+      if (inlineeApiLevelForCode.isEqualTo(appView.computedMinApiLevel())) {
+        return true;
+      }
       whyAreYouNotInliningReporter.reportCallerHasUnknownApiLevel();
       return false;
     }
     // For inlining we only measure if the code has invokes into the library.
-    ComputedApiLevel inlineeApiLevelForCode = inlinee.getDefinition().getApiLevelForCode();
     if (!caller
         .getDefinition()
         .getApiLevelForCode()
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
index dac6de6..9f42bbf 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/EquivalentInstanceInitializerMergingWithApiUnsafeParameterTest.java
@@ -28,7 +28,9 @@
 
   @Parameters(name = "{0}")
   public static TestParametersCollection data() {
-    return getTestParameters().withAllRuntimesAndApiLevels().build();
+    // Always use the min API level to prohibit constructor inlining so that the constructors of
+    // interest are still present at the time of horizontal class merging.
+    return getTestParameters().withAllRuntimes().withMinimumApiLevel().build();
   }
 
   @Test