Enable member rebinding for platform

Bug: 206178274
Change-Id: I37ceb0bcd5a1ed85a4ddc02fd713fa1ae60c36a6
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index fbddc6c..1483137 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -883,20 +883,16 @@
       return true;
     }
     // This will return false if we find anything in the library which is not modeled.
-    appView
-        .appInfo()
-        .classes()
-        .forEach(
-            clazz -> {
-              clazz.forEachProgramMember(
-                  member -> {
-                    assert member.getDefinition().getApiLevel() != AndroidApiLevel.NOT_SET
-                        : "Every member should have been analyzed";
-                    assert appView.options().apiModelingOptions().enableApiCallerIdentification
-                            || member.getDefinition().getApiLevel() == AndroidApiLevel.UNKNOWN
-                        : "Every member should have level UNKNOWN";
-                  });
-            });
+    for (DexProgramClass clazz : appView.appInfo().classesWithDeterministicOrder()) {
+      clazz.forEachProgramMember(
+          member -> {
+            assert member.getDefinition().getApiLevel() != AndroidApiLevel.NOT_SET
+                : "Every member should have been analyzed";
+            assert appView.options().apiModelingOptions().enableApiCallerIdentification
+                    || member.getDefinition().getApiLevel() == AndroidApiLevel.UNKNOWN
+                : "Every member should have level UNKNOWN";
+          });
+    }
     return true;
   }
 
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 3177a9c..a198bb7 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.optimize;
 
+import static com.android.tools.r8.utils.AndroidApiLevelUtils.isApiSafeForMemberRebinding;
+
 import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
@@ -25,7 +27,6 @@
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BiForEachable;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Pair;
@@ -126,7 +127,8 @@
     return resolvedMethod.isLibraryMethod()
         && isAccessibleInAllContexts(resolvedMethod, resolutionResult, contexts)
         && !isInvokeSuperToInterfaceMethod(resolvedMethod, invokeType)
-        && isPresentSinceMinApi(resolvedMethod.asLibraryMethod());
+        && isApiSafeForMemberRebinding(
+            resolvedMethod.asLibraryMethod(), androidApiLevelCompute, options);
   }
 
   private boolean isAccessibleInAllContexts(
@@ -145,13 +147,6 @@
     return method.getHolder().isInterface() && invokeType.isSuper();
   }
 
-  private boolean isPresentSinceMinApi(LibraryMethod method) {
-    AndroidApiLevel apiLevel =
-        androidApiLevelCompute.computeApiLevelForLibraryReference(method.getReference());
-    return apiLevel != AndroidApiLevel.UNKNOWN
-        && apiLevel.isLessThanOrEqualTo(options.getMinApiLevel());
-  }
-
   public static DexField validMemberRebindingTargetFor(
       DexDefinitionSupplier definitions, DexClassAndField field, DexField original) {
     if (field.isProgramField()) {
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
index c348770..b0b7f7f 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
@@ -43,8 +43,9 @@
   R(30),
   S(31),
   Sv2(32),
-  UNKNOWN(10000),
-  NOT_SET(10001);
+  ANDROID_PLATFORM(10000),
+  UNKNOWN(10001),
+  NOT_SET(10002);
 
   // When updating LATEST and a new version goes stable, add a new api-versions.xml to third_party
   // and update the version and generated jar in AndroidApiDatabaseBuilderGeneratorTest.
@@ -107,7 +108,7 @@
 
   public static AndroidApiLevel getAndroidApiLevel(int apiLevel) {
     assert apiLevel > 0;
-    assert UNKNOWN.isGreaterThan(LATEST);
+    assert ANDROID_PLATFORM.isGreaterThan(LATEST);
     switch (apiLevel) {
       case 1:
         return B;
@@ -173,10 +174,12 @@
         return S;
       case 32:
         return Sv2;
+      case 10000:
+        return ANDROID_PLATFORM;
       default:
         // This has to be updated when we add new api levels.
         assert Sv2 == LATEST;
-        return UNKNOWN;
+        return LATEST;
     }
   }
 }
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 73ee4de..c4a7396 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.utils;
 
+import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
+import com.android.tools.r8.graph.LibraryMethod;
 import com.android.tools.r8.graph.ProgramMethod;
 
 public class AndroidApiLevelUtils {
@@ -13,6 +15,10 @@
     if (!options.apiModelingOptions().enableApiCallerIdentification) {
       return true;
     }
+    if (options.isAndroidPlatform()) {
+      // Don't disable inlining in the Android platform based on the Api database.
+      return true;
+    }
     if (caller.getHolderType() == inlinee.getHolderType()) {
       return true;
     }
@@ -21,4 +27,17 @@
         .getApiLevel()
         .isGreaterThanOrEqualTo(inlinee.getDefinition().getApiLevelForCode());
   }
+
+  public static boolean isApiSafeForMemberRebinding(
+      LibraryMethod method,
+      AndroidApiLevelCompute androidApiLevelCompute,
+      InternalOptions options) {
+    AndroidApiLevel apiLevel =
+        androidApiLevelCompute.computeApiLevelForLibraryReference(method.getReference());
+    if (apiLevel == AndroidApiLevel.UNKNOWN) {
+      return false;
+    }
+    assert options.apiModelingOptions().enableApiCallerIdentification;
+    return apiLevel.isLessThanOrEqualTo(options.getMinApiLevel());
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/DexVersion.java b/src/main/java/com/android/tools/r8/utils/DexVersion.java
index 24d374e..241ae90 100644
--- a/src/main/java/com/android/tools/r8/utils/DexVersion.java
+++ b/src/main/java/com/android/tools/r8/utils/DexVersion.java
@@ -40,7 +40,6 @@
     switch (androidApiLevel) {
         // UNKNOWN is an unknown higher api version we therefore choose the highest known
         // version.
-      case UNKNOWN:
       case Sv2:
       case S:
       case R:
@@ -77,7 +76,8 @@
       case L_MR1:
       case M:
         return DexVersion.V35;
-      default :
+      case UNKNOWN:
+      default:
         throw new Unreachable("Unsupported api level " + androidApiLevel);
     }
   }
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 8fd985c..c012686 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -422,6 +422,10 @@
     throw new UnsupportedOperationException("Cannot find internal output mode.");
   }
 
+  public boolean isAndroidPlatform() {
+    return minApiLevel == AndroidApiLevel.ANDROID_PLATFORM;
+  }
+
   public boolean isDesugaredLibraryCompilation() {
     return desugaredLibraryConfiguration.isLibraryCompilation();
   }
@@ -559,7 +563,7 @@
 
   public void setMinApiLevel(AndroidApiLevel minApiLevel) {
     assert minApiLevel != null;
-    assert minApiLevel.isLessThan(AndroidApiLevel.NOT_SET);
+    assert minApiLevel.isLessThan(AndroidApiLevel.UNKNOWN);
     this.minApiLevel = minApiLevel;
   }
 
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 11dfa2d..033e512 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -861,6 +861,7 @@
       case J_MR1:
       case J_MR2:
       case K_WATCH:
+      case ANDROID_PLATFORM:
       case UNKNOWN:
       case NOT_SET:
         return false;