Add host Art 12.0.0-beta4

Test: tools/test.py --no-internal --runtimes=dex-12.0.0
Bug: 197077780
Change-Id: I963f8d3c44ed73969420afe6a7e28a64d3a753ba
diff --git a/.gitignore b/.gitignore
index 80c9662..07f90a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -262,6 +262,8 @@
 tools/*/art-9.0.0.tar.gz
 tools/*/art-10.0.0
 tools/*/art-10.0.0.tar.gz
+tools/*/host/art-12.0.0-beta4
+tools/*/host/art-12.0.0-beta4.tar.gz
 tools/*/art.tar.gz
 tools/*/dalvik
 tools/*/dalvik-4.0.4
diff --git a/build.gradle b/build.gradle
index 4a8dd81..8b0525f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -361,6 +361,7 @@
                 "linux/art-8.1.0",
                 "linux/art-9.0.0",
                 "linux/art-10.0.0",
+                "linux/host/art-12.0.0-beta4",
                 "linux/dalvik",
                 "linux/dalvik-4.0.4",
                 "${osString}/dx",
diff --git a/scripts/update-host-art.sh b/scripts/update-host-art.sh
index 76572e0..58165cd 100755
--- a/scripts/update-host-art.sh
+++ b/scripts/update-host-art.sh
@@ -109,11 +109,15 @@
 # dalvikvm32 or dalvikvm64).
 cp $ANDROID_HOST_BUILD/bin/dalvikvm $DEST/bin
 cp $ANDROID_HOST_BUILD/bin/dex2oat $DEST/bin
+if [ -e $ANDROID_HOST_BUILD/bin/dex2oat64 ]
+  then cp $ANDROID_HOST_BUILD/bin/dex2oat64 $DEST/bin
+fi
 if [ -e $ANDROID_HOST_BUILD/bin/patchoat ]
   # File patchoat does not exist on Q anymore.
   then cp $ANDROID_HOST_BUILD/bin/patchoat $DEST/bin
 fi
 
+
 # Required framework files.
 mkdir -p $DEST/framework
 cp -R $ANDROID_HOST_BUILD/framework/* $DEST/framework
@@ -127,15 +131,32 @@
 # Image files required for dex2oat of actual android apps. We need an actual android product
 # image containing framework classes to verify the code against.
 mkdir -p $DEST/product/$ANDROID_PRODUCT/system/framework
-cp -r $ANDROID_TARGET_BUILD/product/$ANDROID_PRODUCT/system/framework/* $DEST/product/$ANDROID_PRODUCT/system/framework
+cp -rL $ANDROID_TARGET_BUILD/product/$ANDROID_PRODUCT/system/framework/* $DEST/product/$ANDROID_PRODUCT/system/framework
 
 # Required auxillary files.
-if [ -e $ANDROID_HOST_BUILD/usr/icu ]; then
-  mkdir -p $DEST/usr/icu
-  cp -r $ANDROID_HOST_BUILD/usr/icu/* $DEST/usr/icu
+if [ -e $ANDROID_HOST_BUILD/apex ]; then
+  mkdir -p $DEST/apex
+  cp -rL $ANDROID_HOST_BUILD/apex/* $DEST/apex
+  if [ -e $ANDROID_HOST_BUILD/com.android.i18n ]; then
+    mkdir -p $DEST/com.android.i18n
+    cp -r $ANDROID_HOST_BUILD/com.android.i18n/* $DEST/com.android.i18n
+  fi
+  if [ -e $ANDROID_HOST_BUILD/com.android.tzdata ]; then
+    mkdir -p $DEST/com.android.tzdata
+    cp -r $ANDROID_HOST_BUILD/com.android.tzdata/* $DEST/com.android.tzdata
+  fi
+  if [ -e $ANDROID_HOST_BUILD/usr ]; then
+    mkdir -p $DEST/usr
+    cp -r $ANDROID_HOST_BUILD/usr/* $DEST/usr
+  fi
 else
-  mkdir -p $DEST/com.android.runtime/etc/icu/
-  cp -r $ANDROID_HOST_BUILD/com.android.runtime/etc/icu/* $DEST/com.android.runtime/etc/icu/
+  if [ -e $ANDROID_HOST_BUILD/usr/icu ]; then
+    mkdir -p $DEST/usr/icu
+    cp -r $ANDROID_HOST_BUILD/usr/icu/* $DEST/usr/icu
+  else
+    mkdir -p $DEST/com.android.runtime/etc/icu/
+    cp -r $ANDROID_HOST_BUILD/com.android.runtime/etc/icu/* $DEST/com.android.runtime/etc/icu/
+  fi
 fi
 
 # Update links for vdex files for Android P and later.
@@ -166,3 +187,4 @@
 
 echo "Now run"
 echo "(cd $DEST_ROOT; upload_to_google_storage.py -a --bucket r8-deps $ART_DIR)"
+echo "NOTE; If $ART_DIR has several directory elements adjust accordingly."
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java b/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
index d8e0196..848c566 100644
--- a/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
+++ b/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
@@ -116,8 +116,12 @@
                     containsString(
                         "java.lang.NoClassDefFoundError: "
                             + "Failed resolution of: Ljava/util/concurrent/Flow$Subscriber;"),
-                    // Art 10+.
-                    containsString("java.lang.ClassNotFoundException: MySubscriber")));
+                    // Art 10.
+                    containsString("java.lang.ClassNotFoundException: MySubscriber"),
+                    // Art 11+.
+                    containsString(
+                        "java.lang.ClassNotFoundException: "
+                            + "java.util.concurrent.SubmissionPublisher")));
       } else {
         if (parameters.getRuntime().asCf().getVm() == CfVm.JDK8) {
           // java.util.concurrent.Flow$Subscriber not present in JDK8.
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index bcd4fea..f58f1fd 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -95,15 +95,17 @@
   private static final String ART_TESTS_NATIVE_LIBRARY_DIR = "tests/2017-10-04/art/lib64";
   private static final String ART_LEGACY_TESTS_NATIVE_LIBRARY_DIR = "tests/2016-12-19/art/lib64";
 
-  private static final RuntimeSet LEGACY_RUNTIME = TestCondition.runtimes(
-      DexVm.Version.V4_0_4,
-      DexVm.Version.V4_4_4,
-      DexVm.Version.V5_1_1,
-      DexVm.Version.V6_0_1,
-      DexVm.Version.V7_0_0,
-      DexVm.Version.V8_1_0,
-      DexVm.Version.V9_0_0,
-      DexVm.Version.V10_0_0);
+  private static final RuntimeSet LEGACY_RUNTIME =
+      TestCondition.runtimes(
+          DexVm.Version.V4_0_4,
+          DexVm.Version.V4_4_4,
+          DexVm.Version.V5_1_1,
+          DexVm.Version.V6_0_1,
+          DexVm.Version.V7_0_0,
+          DexVm.Version.V8_1_0,
+          DexVm.Version.V9_0_0,
+          DexVm.Version.V10_0_0,
+          DexVm.Version.V12_0_0);
 
   // Input jar for jctf tests.
   private static final String JCTF_COMMON_JAR = "build/libs/jctfCommon.jar";
@@ -185,6 +187,18 @@
           .put(
               "134-reg-promotion",
               TestCondition.match(TestCondition.runtimes(DexVm.Version.V10_0_0)))
+          // TODO(b/197078742): Triage - test OOMs.
+          .put(
+              "134-reg-promotion",
+              TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
+          // TODO(b/197078746): Triage - fails with "java.lang.NoSuchMethodException:
+          //  org.apache.harmony.dalvik.ddmc.DdmVmInternal.enableRecentAllocations [boolean]"
+          .put("098-ddmc", TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
+          // TODO(b/197079442): Triage - fails with "java.lang.NoSuchMethodException:
+          //  org.apache.harmony.dalvik.ddmc.DdmVmInternal.enableRecentAllocations [boolean]"
+          .put(
+              "145-alloc-tracking-stress",
+              TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
           .build();
 
   // Tests that are flaky with the Art version we currently use.
@@ -488,115 +502,134 @@
   static {
     ImmutableMap.Builder<DexVm.Version, List<String>> builder = ImmutableMap.builder();
     builder
-        .put(DexVm.Version.V10_0_0, ImmutableList.of(
-            // TODO(b/144975341): Triage, Verif error.
-            "518-null-array-get",
-            // TODO(b/144975341): Triage, Linking error.
-            "457-regs",
-            "543-env-long-ref",
-            "454-get-vreg"
-        ))
-        .put(DexVm.Version.V9_0_0, ImmutableList.of(
-            // TODO(120400625): Triage.
-            "454-get-vreg",
-            // TODO(120402198): Triage.
-            "457-regs",
-            // TODO(120401674): Triage.
-            "543-env-long-ref",
-            // TODO(120261858) Triage.
-            "518-null-array-get"
-        ))
-        .put(DexVm.Version.V8_1_0, ImmutableList.of(
-            // TODO(119938529): Triage.
-            "709-checker-varhandles",
-            "454-get-vreg",
-            "457-regs"
-        ))
-        .put(DexVm.Version.V7_0_0, ImmutableList.of(
-            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
-            "008-exceptions",
+        .put(
+            DexVm.Version.V12_0_0,
+            ImmutableList.of("454-get-vreg", "457-regs", "543-env-long-ref", "518-null-array-get"))
+        .put(
+            DexVm.Version.V10_0_0,
+            ImmutableList.of(
+                // TODO(b/144975341): Triage, Verif error.
+                "518-null-array-get",
+                // TODO(b/144975341): Triage, Linking error.
+                "457-regs",
+                "543-env-long-ref",
+                "454-get-vreg"))
+        .put(
+            DexVm.Version.V9_0_0,
+            ImmutableList.of(
+                // TODO(120400625): Triage.
+                "454-get-vreg",
+                // TODO(120402198): Triage.
+                "457-regs",
+                // TODO(120401674): Triage.
+                "543-env-long-ref",
+                // TODO(120261858) Triage.
+                "518-null-array-get"))
+        .put(
+            DexVm.Version.V8_1_0,
+            ImmutableList.of(
+                // TODO(119938529): Triage.
+                "709-checker-varhandles", "454-get-vreg", "457-regs"))
+        .put(
+            DexVm.Version.V7_0_0,
+            ImmutableList.of(
+                // Addition of checks for super-class-initialization cause this to abort on non-ToT
+                // art.
+                "008-exceptions",
 
-            // Generally fails on non-R8/D8 running.
-            "156-register-dex-file-multi-loader",
-            "412-new-array",
-            "610-arraycopy",
-            "625-checker-licm-regressions"))
-        .put(DexVm.Version.V6_0_1, ImmutableList.of(
-            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
-            "008-exceptions",
+                // Generally fails on non-R8/D8 running.
+                "156-register-dex-file-multi-loader",
+                "412-new-array",
+                "610-arraycopy",
+                "625-checker-licm-regressions"))
+        .put(
+            DexVm.Version.V6_0_1,
+            ImmutableList.of(
+                // Addition of checks for super-class-initialization cause this to abort on non-ToT
+                // art.
+                "008-exceptions",
 
-            // Generally fails on non-R8/D8 running.
-            "004-checker-UnsafeTest18",
-            "005-annotations",
-            "008-exceptions",
-            "082-inline-execute",
-            "099-vmdebug",
-            "156-register-dex-file-multi-loader",
-            "412-new-array",
-            "580-checker-round",
-            "594-invoke-super",
-            "625-checker-licm-regressions",
-            "626-const-class-linking"))
-        .put(DexVm.Version.V5_1_1, ImmutableList.of(
-            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
-            "008-exceptions",
+                // Generally fails on non-R8/D8 running.
+                "004-checker-UnsafeTest18",
+                "005-annotations",
+                "008-exceptions",
+                "082-inline-execute",
+                "099-vmdebug",
+                "156-register-dex-file-multi-loader",
+                "412-new-array",
+                "580-checker-round",
+                "594-invoke-super",
+                "625-checker-licm-regressions",
+                "626-const-class-linking"))
+        .put(
+            DexVm.Version.V5_1_1,
+            ImmutableList.of(
+                // Addition of checks for super-class-initialization cause this to abort on non-ToT
+                // art.
+                "008-exceptions",
 
-            // Generally fails on non R8/D8 running.
-            "004-checker-UnsafeTest18",
-            "004-NativeAllocations",
-            "005-annotations",
-            "008-exceptions",
-            "082-inline-execute",
-            "099-vmdebug",
-            "143-string-value",
-            "156-register-dex-file-multi-loader",
-            "536-checker-intrinsic-optimization",
-            "552-invoke-non-existent-super",
-            "580-checker-round",
-            "580-checker-string-fact-intrinsics",
-            "594-invoke-super",
-            "605-new-string-from-bytes",
-            "626-const-class-linking"))
-        .put(DexVm.Version.V4_4_4, ImmutableList.of(
-            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
-            "008-exceptions",
+                // Generally fails on non R8/D8 running.
+                "004-checker-UnsafeTest18",
+                "004-NativeAllocations",
+                "005-annotations",
+                "008-exceptions",
+                "082-inline-execute",
+                "099-vmdebug",
+                "143-string-value",
+                "156-register-dex-file-multi-loader",
+                "536-checker-intrinsic-optimization",
+                "552-invoke-non-existent-super",
+                "580-checker-round",
+                "580-checker-string-fact-intrinsics",
+                "594-invoke-super",
+                "605-new-string-from-bytes",
+                "626-const-class-linking"))
+        .put(
+            DexVm.Version.V4_4_4,
+            ImmutableList.of(
+                // Addition of checks for super-class-initialization cause this to abort on non-ToT
+                // art.
+                "008-exceptions",
 
-            // Generally fails on non R8/D8 running.
-            "004-checker-UnsafeTest18",
-            "004-NativeAllocations",
-            "005-annotations",
-            "008-exceptions",
-            "082-inline-execute",
-            "099-vmdebug",
-            "143-string-value",
-            "156-register-dex-file-multi-loader",
-            "536-checker-intrinsic-optimization",
-            "552-invoke-non-existent-super",
-            "580-checker-round",
-            "580-checker-string-fact-intrinsics",
-            "594-invoke-super",
-            "605-new-string-from-bytes",
-            "626-const-class-linking"))
-        .put(DexVm.Version.V4_0_4, ImmutableList.of(
-            // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
-            "008-exceptions",
+                // Generally fails on non R8/D8 running.
+                "004-checker-UnsafeTest18",
+                "004-NativeAllocations",
+                "005-annotations",
+                "008-exceptions",
+                "082-inline-execute",
+                "099-vmdebug",
+                "143-string-value",
+                "156-register-dex-file-multi-loader",
+                "536-checker-intrinsic-optimization",
+                "552-invoke-non-existent-super",
+                "580-checker-round",
+                "580-checker-string-fact-intrinsics",
+                "594-invoke-super",
+                "605-new-string-from-bytes",
+                "626-const-class-linking"))
+        .put(
+            DexVm.Version.V4_0_4,
+            ImmutableList.of(
+                // Addition of checks for super-class-initialization cause this to abort on non-ToT
+                // art.
+                "008-exceptions",
 
-            // Generally fails on non R8/D8 running.
-            "004-checker-UnsafeTest18",
-            "004-NativeAllocations",
-            "005-annotations",
-            "008-exceptions",
-            "082-inline-execute",
-            "099-vmdebug",
-            "143-string-value",
-            "156-register-dex-file-multi-loader",
-            "536-checker-intrinsic-optimization",
-            "552-invoke-non-existent-super",
-            "580-checker-round",
-            "580-checker-string-fact-intrinsics",
-            "594-invoke-super",
-            "605-new-string-from-bytes",
-            "626-const-class-linking"));
+                // Generally fails on non R8/D8 running.
+                "004-checker-UnsafeTest18",
+                "004-NativeAllocations",
+                "005-annotations",
+                "008-exceptions",
+                "082-inline-execute",
+                "099-vmdebug",
+                "143-string-value",
+                "156-register-dex-file-multi-loader",
+                "536-checker-intrinsic-optimization",
+                "552-invoke-non-existent-super",
+                "580-checker-round",
+                "580-checker-string-fact-intrinsics",
+                "594-invoke-super",
+                "605-new-string-from-bytes",
+                "626-const-class-linking"));
     expectedToFailRunWithArtVersion = builder.build();
   }
 
@@ -2050,6 +2083,10 @@
           System.out.println("Running on 10.0.0 is disabled, see b/144966342");
           continue;
         }
+        if (vm.getVersion() == DexVm.Version.V12_0_0) {
+          System.out.println("Running on 12.0.0 is disabled, see b/197078995");
+          continue;
+        }
         vms.add(new DexRuntime(vm));
       }
     }
diff --git a/src/test/java/com/android/tools/r8/TestCondition.java b/src/test/java/com/android/tools/r8/TestCondition.java
index d72ba77..07fff0e 100644
--- a/src/test/java/com/android/tools/r8/TestCondition.java
+++ b/src/test/java/com/android/tools/r8/TestCondition.java
@@ -25,6 +25,7 @@
     ART_V8_1_0,
     ART_V9_0_0,
     ART_V10_0_0,
+    ART_V12_0_0,
     ART_DEFAULT,
     JAVA;
 
@@ -49,6 +50,8 @@
           return ART_V9_0_0;
         case V10_0_0:
           return ART_V10_0_0;
+        case V12_0_0:
+          return ART_V12_0_0;
         case DEFAULT:
           return ART_DEFAULT;
         default:
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index a1bdeb8..a38852e 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -256,7 +256,9 @@
     ART_9_0_0_TARGET(Version.V9_0_0, Kind.TARGET),
     ART_9_0_0_HOST(Version.V9_0_0, Kind.HOST),
     ART_10_0_0_TARGET(Version.V10_0_0, Kind.TARGET),
-    ART_10_0_0_HOST(Version.V10_0_0, Kind.HOST);
+    ART_10_0_0_HOST(Version.V10_0_0, Kind.HOST),
+    ART_12_0_0_TARGET(Version.V12_0_0, Kind.TARGET),
+    ART_12_0_0_HOST(Version.V12_0_0, Kind.HOST);
 
     private static final ImmutableMap<String, DexVm> SHORT_NAME_MAP =
         Arrays.stream(DexVm.values()).collect(ImmutableMap.toImmutableMap(
@@ -271,7 +273,8 @@
       V8_1_0("8.1.0"),
       DEFAULT("default"),
       V9_0_0("9.0.0"),
-      V10_0_0("10.0.0");
+      V10_0_0("10.0.0"),
+      V12_0_0("12.0.0");
 
       Version(String shortName) {
         this.shortName = shortName;
@@ -289,6 +292,10 @@
         return this == last();
       }
 
+      public boolean isEqualTo(Version other) {
+        return compareTo(other) == 0;
+      }
+
       public boolean isNewerThan(Version other) {
         return compareTo(other) > 0;
       }
@@ -321,7 +328,7 @@
       }
 
       public static Version last() {
-        return V10_0_0;
+        return V12_0_0;
       }
 
       static {
@@ -358,10 +365,22 @@
       return SHORT_NAME_MAP.get(version.shortName + "_" + Kind.HOST.toString());
     }
 
+    public boolean isEqualTo(DexVm other) {
+      return version.isNewerThanOrEqual(other.version);
+    }
+
     public boolean isNewerThan(DexVm other) {
       return version.isNewerThan(other.version);
     }
 
+    public boolean isNewerThanOrEqual(DexVm other) {
+      return version.isNewerThanOrEqual(other.version);
+    }
+
+    public boolean isOlderThan(DexVm other) {
+      return version.isOlderThan(other.version);
+    }
+
     public boolean isOlderThanOrEqual(DexVm other) {
       return version.isOlderThanOrEqual(other.version);
     }
@@ -580,6 +599,7 @@
   private static final Map<DexVm, String> ART_DIRS =
       ImmutableMap.<DexVm, String>builder()
           .put(DexVm.ART_DEFAULT, "art")
+          .put(DexVm.ART_12_0_0_HOST, "host/art-12.0.0-beta4")
           .put(DexVm.ART_10_0_0_HOST, "art-10.0.0")
           .put(DexVm.ART_9_0_0_HOST, "art-9.0.0")
           .put(DexVm.ART_8_1_0_HOST, "art-8.1.0")
@@ -587,10 +607,12 @@
           .put(DexVm.ART_6_0_1_HOST, "art-6.0.1")
           .put(DexVm.ART_5_1_1_HOST, "art-5.1.1")
           .put(DexVm.ART_4_4_4_HOST, "dalvik")
-          .put(DexVm.ART_4_0_4_HOST, "dalvik-4.0.4").build();
+          .put(DexVm.ART_4_0_4_HOST, "dalvik-4.0.4")
+          .build();
   private static final Map<DexVm, String> ART_BINARY_VERSIONS =
       ImmutableMap.<DexVm, String>builder()
           .put(DexVm.ART_DEFAULT, "bin/art")
+          .put(DexVm.ART_12_0_0_HOST, "bin/art")
           .put(DexVm.ART_10_0_0_HOST, "bin/art")
           .put(DexVm.ART_9_0_0_HOST, "bin/art")
           .put(DexVm.ART_8_1_0_HOST, "bin/art")
@@ -598,16 +620,19 @@
           .put(DexVm.ART_6_0_1_HOST, "bin/art")
           .put(DexVm.ART_5_1_1_HOST, "bin/art")
           .put(DexVm.ART_4_4_4_HOST, "bin/dalvik")
-          .put(DexVm.ART_4_0_4_HOST, "bin/dalvik").build();
+          .put(DexVm.ART_4_0_4_HOST, "bin/dalvik")
+          .build();
 
   private static final Map<DexVm, String> ART_BINARY_VERSIONS_X64 =
       ImmutableMap.<DexVm, String>builder()
           .put(DexVm.ART_DEFAULT, "bin/art")
+          .put(DexVm.ART_12_0_0_HOST, "bin/art")
           .put(DexVm.ART_10_0_0_HOST, "bin/art")
           .put(DexVm.ART_9_0_0_HOST, "bin/art")
           .put(DexVm.ART_8_1_0_HOST, "bin/art")
           .put(DexVm.ART_7_0_0_HOST, "bin/art")
-          .put(DexVm.ART_6_0_1_HOST, "bin/art").build();
+          .put(DexVm.ART_6_0_1_HOST, "bin/art")
+          .build();
 
   private static final List<String> DALVIK_BOOT_LIBS =
       ImmutableList.of(
@@ -627,6 +652,7 @@
     ImmutableMap.Builder<DexVm, List<String>> builder = ImmutableMap.builder();
     builder
         .put(DexVm.ART_DEFAULT, ART_BOOT_LIBS)
+        .put(DexVm.ART_12_0_0_HOST, ART_BOOT_LIBS)
         .put(DexVm.ART_10_0_0_HOST, ART_BOOT_LIBS)
         .put(DexVm.ART_9_0_0_HOST, ART_BOOT_LIBS)
         .put(DexVm.ART_8_1_0_HOST, ART_BOOT_LIBS)
@@ -644,6 +670,7 @@
     ImmutableMap.Builder<DexVm, String> builder = ImmutableMap.builder();
     builder
         .put(DexVm.ART_DEFAULT, "angler")
+        .put(DexVm.ART_12_0_0_HOST, "redfin")
         .put(DexVm.ART_10_0_0_HOST, "coral")
         .put(DexVm.ART_9_0_0_HOST, "marlin")
         .put(DexVm.ART_8_1_0_HOST, "marlin")
@@ -1002,6 +1029,8 @@
     switch (dexVm.version) {
       case DEFAULT:
         return AndroidApiLevel.O;
+      case V12_0_0:
+        return AndroidApiLevel.S;
       case V10_0_0:
         return AndroidApiLevel.Q;
       case V9_0_0:
@@ -1898,7 +1927,8 @@
   public static ProcessResult runDex2OatRaw(Path file, Path outFile, DexVm vm) throws IOException {
     // TODO(jmhenaff): find a way to run this on windows (push dex and run on device/emulator?)
     Assume.assumeTrue(ToolHelper.isDex2OatSupported());
-    Assume.assumeFalse("b/144975341", vm.version == DexVm.Version.V10_0_0);
+    Assume.assumeFalse(
+        "b/144975341", vm.version == DexVm.Version.V10_0_0 || vm.version == DexVm.Version.V12_0_0);
     if (vm.isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
       // Run default dex2oat for tests on dalvik runtimes.
       vm = DexVm.ART_DEFAULT;
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
index 04337ec..c87f2cc 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
@@ -7,7 +7,7 @@
 import static com.android.tools.r8.apimodel.ApiModelingTestHelper.addTracedApiReferenceLevelCallBack;
 import static com.android.tools.r8.utils.AndroidApiLevel.LATEST;
 import static com.android.tools.r8.utils.AndroidApiLevel.R;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
@@ -56,7 +56,7 @@
             addTracedApiReferenceLevelCallBack(
                 (method, apiLevel) -> {
                   if (Reference.methodFromMethod(main).equals(method)) {
-                    assertEquals(R, apiLevel);
+                    assertTrue(apiLevel.isGreaterThanOrEqualTo(R));
                   }
                 }))
         .compile();
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
index 37aa606..81038d6 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
@@ -4,17 +4,18 @@
 
 package com.android.tools.r8.desugar.backports;
 
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
 @RunWith(Parameterized.class)
 public final class ByteBackportJava9Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
@@ -31,7 +32,8 @@
 
   public ByteBackportJava9Test(TestParameters parameters) {
     super(parameters, Byte.class, TEST_JAR, "backport.ByteBackportJava9Main");
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to ByteBackportTest.
+
+    // Byte.compareUnsigned added in API 31.
+    registerTarget(AndroidApiLevel.S, 16);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
index 309b319..7b80e96 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
@@ -4,9 +4,12 @@
 
 package com.android.tools.r8.desugar.backports;
 
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
@@ -14,8 +17,6 @@
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
 @RunWith(Parameterized.class)
 public class ListBackportJava10Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
@@ -40,5 +41,8 @@
     ignoreInvokes("get");
     ignoreInvokes("set");
     ignoreInvokes("size");
+
+    // List.copyOf added in API 31.
+    registerTarget(AndroidApiLevel.S, 3);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
index 0d55065..ddf502b 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
@@ -44,13 +44,16 @@
     ignoreInvokes("get");
     ignoreInvokes("set");
     ignoreInvokes("size");
+
+    // List.of added in API 30.
+    registerTarget(AndroidApiLevel.R, 18);
   }
 
   @Test
   public void desugaringApiLevelR() throws Exception {
-    // TODO(154759404): This test should start to fail when testing on an Android R VM.
-    if (parameters.getRuntime().isDex()
-        && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.Q)) {
       testForD8()
           .setMinApi(AndroidApiLevel.R)
           .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
index e54d7d8..11008cc 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
@@ -4,9 +4,12 @@
 
 package com.android.tools.r8.desugar.backports;
 
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Map;
@@ -14,8 +17,6 @@
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
 @RunWith(Parameterized.class)
 public class MapBackportJava10Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
@@ -40,5 +41,8 @@
     ignoreInvokes("get");
     ignoreInvokes("put");
     ignoreInvokes("size");
+
+    // Map.copyOf added in API 31.
+    registerTarget(AndroidApiLevel.S, 4);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
index 27cb824..73ffa29 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
@@ -44,13 +44,16 @@
     ignoreInvokes("get");
     ignoreInvokes("put");
     ignoreInvokes("size");
+
+    // Map.entry, Map.of and Map.ofEntries added in API 30.
+    registerTarget(AndroidApiLevel.R, 29);
   }
 
   @Test
   public void desugaringApiLevelR() throws Exception {
-    // TODO(154759404): This test should start to fail when testing on an Android R VM.
-    if (parameters.getRuntime().isDex()
-        && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
       testForD8()
           .setMinApi(AndroidApiLevel.R)
           .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
index 387697e..2f70fc2 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import org.junit.runner.RunWith;
@@ -31,7 +32,9 @@
 
   public MathBackportJava9Test(TestParameters parameters) {
     super(parameters, Math.class, TEST_JAR, "backport.MathBackportJava9Main");
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to MathBackportTest.
+
+    // Math.floorDiv, Math.floorMod, Math.multiplyExact, Math.multiplyFull and Math.multiplyHigh
+    // added in API 31.
+    registerTarget(AndroidApiLevel.S, 27);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
index 09aef1e..527d2c0 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Objects;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -34,16 +35,20 @@
   private static final String TEST_CLASS = "backport.ObjectsBackportJava9Main";
 
   public ObjectsBackportJava9Test(TestParameters parameters) {
-    super(parameters, Short.class, TEST_JAR, TEST_CLASS);
+    super(parameters, Objects.class, TEST_JAR, TEST_CLASS);
     // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
     // an actual API level, migrate these tests to ObjectsBackportTest.
+
+    // Objects.checkFromIndexSize, Objects.checkFromToIndex, Objects.checkIndex,
+    // Objects.requireNonNullElse and Objects.requireNonNullElseGet added in API 30.
+    registerTarget(AndroidApiLevel.R, 28);
   }
 
   @Test
   public void desugaringApiLevelR() throws Exception {
-    // TODO(154759404): This test should start to fail when testing on an Android R VM.
-    if (parameters.getRuntime().isDex()
-        && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added chck and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
       testForD8()
           .setMinApi(AndroidApiLevel.R)
           .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
index 5c08b8f..2a17cb2 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
@@ -4,9 +4,12 @@
 
 package com.android.tools.r8.desugar.backports;
 
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Set;
@@ -14,8 +17,6 @@
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
 @RunWith(Parameterized.class)
 public class SetBackportJava10Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
@@ -39,5 +40,10 @@
     ignoreInvokes("add");
     ignoreInvokes("contains");
     ignoreInvokes("size");
+
+    // Set.of added in API 30
+    registerTarget(AndroidApiLevel.R, 1);
+    // Set.copyOf added in API 31
+    registerTarget(AndroidApiLevel.S, 5);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
index 408b203..652cde0 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
@@ -43,13 +43,16 @@
     ignoreInvokes("add");
     ignoreInvokes("contains");
     ignoreInvokes("size");
+
+    // Set.of added in API 30.
+    registerTarget(AndroidApiLevel.R, 21);
   }
 
   @Test
   public void desugaringApiLevelR() throws Exception {
-    // TODO(154759404): This test should start to fail when testing on an Android R VM.
-    if (parameters.getRuntime().isDex()
-        && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+    // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+    // This has now been checked with S, when R testing is added check and remove this.
+    if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
       testForD8()
           .setMinApi(AndroidApiLevel.R)
           .addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
index beffd8a..d1d3c95 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
@@ -4,17 +4,18 @@
 
 package com.android.tools.r8.desugar.backports;
 
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
 @RunWith(Parameterized.class)
 public final class ShortBackportJava9Test extends AbstractBackportTest {
   @Parameters(name = "{0}")
@@ -31,7 +32,8 @@
 
   public ShortBackportJava9Test(TestParameters parameters) {
     super(parameters, Short.class, TEST_JAR, "backport.ShortBackportJava9Main");
-    // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
-    // an actual API level, migrate these tests to ShortBackportTest.
+
+    // Short.compareUnsigned added in API 31.
+    registerTarget(AndroidApiLevel.S, 16);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java b/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
index 61cf95d..1ebfe97 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
@@ -5,6 +5,8 @@
 package com.android.tools.r8.desugar.backports;
 
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
 import org.junit.runner.RunWith;
@@ -24,18 +26,29 @@
   public SparseArrayBackportTest(TestParameters parameters) throws IOException {
     super(
         parameters,
-        SparseArrayBackportTest.getSparseArray(),
+        SparseArrayBackportTest.getSparseArray(parameters),
         ImmutableList.of(
-            SparseArrayBackportTest.getTestRunner(), SparseArrayBackportTest.getSparseArray()));
+            SparseArrayBackportTest.getTestRunner(),
+            SparseArrayBackportTest.getSparseArray(parameters)));
 
     // The constructor is used by the test and put has been available since API 1 and is the
     // method set is rewritten to.
     ignoreInvokes("<init>");
     ignoreInvokes("put");
+
+    // android.util.SparseArray.set added in API 31.
+    registerTarget(AndroidApiLevel.S, 1);
   }
 
-  private static byte[] getSparseArray() throws IOException {
-    return transformer(SparseArray.class).setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR).transform();
+  private static byte[] getSparseArray(TestParameters parameters) throws IOException {
+    if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.S)) {
+      assert parameters.getRuntime().asDex().getVm().isNewerThanOrEqual(DexVm.ART_12_0_0_HOST);
+      return transformer(SparseArrayAndroid12.class)
+          .setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR)
+          .transform();
+    } else {
+      return transformer(SparseArray.class).setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR).transform();
+    }
   }
 
   private static byte[] getTestRunner() throws IOException {
@@ -56,6 +69,17 @@
     }
   }
 
+  public static class SparseArrayAndroid12 {
+    public void set(int index, Object value) {
+      TestRunner.doAssertEquals(42, index);
+      TestRunner.doAssertEquals("Forty two", value);
+    }
+
+    public void put(int index, Object value) {
+      TestRunner.doFail("put should not be called");
+    }
+  }
+
   public static class TestRunner extends MiniAssert {
 
     public static void main(String[] args) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
index c8ddd5d..80828b1 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.D8TestRunResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
@@ -35,7 +35,6 @@
     return buildParameters(
         BooleanUtils.values(),
         getTestParameters()
-            .withDexRuntimesStartingFromIncluding(Version.V5_1_1)
             .withAllApiLevels()
             .withApiLevel(AndroidApiLevel.N)
             .build());
@@ -134,6 +133,10 @@
 
   @Test
   public void testTime() throws Exception {
+    if (parameters.getRuntime().asDex().getVm().isEqualTo(DexVm.ART_12_0_0_HOST)) {
+      // TODO(b/197078988): Many additional tests fails with Android 12.
+      return;
+    }
     KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     String verbosity = "2";
     D8TestCompileResult compileResult =
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
index cd2b968..363e539 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
@@ -111,13 +111,6 @@
         result.assertSuccessWithOutput(EXPECTED);
         return;
       }
-      if (!unexpectedArtFailure() && !parameters.canUseDefaultAndStaticInterfaceMethods()) {
-        assert false : "Dead code until future ART behavior change. See b/152199517";
-        // Desugaring will insert a forwarding bridge which will hide the "invalid invoke" case.
-        // Thus, a future ART runtime that does not have the invalid IAE for the private override
-        // will end up calling the forward method to I.m.
-        result.assertSuccessWithOutput(EXPECTED);
-      }
       // The expected behavior is IAE since the resolved method is private.
       result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
       return;
@@ -142,7 +135,8 @@
 
   private boolean unexpectedArtFailure() {
     return parameters.isDexRuntime()
-        && parameters.getRuntime().asDex().getVm().isNewerThan(DexVm.ART_6_0_1_HOST);
+        && parameters.getRuntime().asDex().getVm().isNewerThan(DexVm.ART_6_0_1_HOST)
+        && parameters.getRuntime().asDex().getVm().isOlderThan(DexVm.ART_12_0_0_HOST);
   }
 
   static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
index 92f5365..12869e2 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
@@ -116,7 +116,8 @@
 
     if (isR8
         && parameters.isDexRuntime()
-        && parameters.getDexRuntimeVersion().isNewerThan(Version.V6_0_1)) {
+        && parameters.getDexRuntimeVersion().isNewerThan(Version.V6_0_1)
+        && parameters.getDexRuntimeVersion().isOlderThan(Version.V12_0_0)) {
       // TODO(b/182255398): This should be EXPECTED.
       result.assertSuccessWithOutput(EXPECTED_R8);
       return;
diff --git a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
index efa7b4e..e110f57 100644
--- a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
@@ -74,6 +74,7 @@
               case V4_0_4:
               case V4_4_4:
               case V10_0_0:
+              case V12_0_0:
                 return StringUtils.joinLines("Hello!", "Goodbye!", "");
 
               case V7_0_0:
diff --git a/tools/linux/README.art-versions b/tools/linux/README.art-versions
index 9cf0717..ff57695 100644
--- a/tools/linux/README.art-versions
+++ b/tools/linux/README.art-versions
@@ -41,6 +41,33 @@
   repo init -u https://android.googlesource.com/platform/manifest -m aosp_master_manifest.xml
   <continue with repo sync as above>
 
+
+art-12.0.0 (Android S)
+---------------------
+Build from branch sc-beta4-release.
+
+export BRANCH=sc-beta4-release
+mkdir ${BRANCH}
+cd ${BRANCH}
+repo init -u https://android.googlesource.com/platform/manifest -b ${BRANCH}
+repo sync -cq -j24
+source build/envsetup.sh
+lunch aosp_redfin-userdebug
+m -j48
+m -j48 build-art
+m -j48 test-art-host
+
+Collected into tools/linux/host/art-12.0.0-beta4. The "host" path element is checked
+by the script for running Art.
+
+  cd <r8 checkout>
+  scripts/update-host-art.sh \
+     --android-checkout /usr/local/ssd/android/${BRANCH} \
+     --art-dir host/art-12.0.0-beta4 \
+     --android-product redfin
+
+(cd tools/linux/host; upload_to_google_storage.py -a --bucket r8-deps art-12.0.0-beta4)
+
 art-10.0.0 (Android Q)
 ---------------------
 Build from branch android-10.0.0_r14.
diff --git a/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1 b/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1
new file mode 100644
index 0000000..b95d909
--- /dev/null
+++ b/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1
@@ -0,0 +1 @@
+9b6d0b061669e0fb1b09ba92c3650d5c7bdc9e85
\ No newline at end of file
diff --git a/tools/test.py b/tools/test.py
index 9c35352..6553358 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -23,6 +23,7 @@
 
 ALL_ART_VMS = [
     "default",
+    "12.0.0",
     "10.0.0",
     "9.0.0",
     "8.1.0",