Snap for 10453563 from f0abff70c16cd0a8f16a68cf6b24adb083fa7ab9 to mainline-mediaprovider-release

Change-Id: Ifecaeaa6a749be433e42a943f54c9106a2c2be54
diff --git a/Android.bp b/Android.bp
index 33d2ea8..c12f012 100644
--- a/Android.bp
+++ b/Android.bp
@@ -54,27 +54,6 @@
     name: "robolectric_build_props",
 }
 
-// package the framework raw/uncompiled resources and assets into a jar
-// This logic can be removed once the transition to binary resources is complete
-java_library {
-    name: "robolectric_framework_raw_res_orig",
-    java_resources: [":robolectric_framework_raw_res_files"],
-}
-
-// Move the raw/uncompiled resources and assets into raw-res/
-// This logic can be removed once the transition to binary resources is complete
-java_genrule_host {
-    name: "robolectric_framework_raw_res",
-    out: ["robolectric_framework_raw_res.jar"],
-    srcs: [":robolectric_framework_raw_res_orig"],
-    tools: ["zip2zip"],
-    cmd: "$(location zip2zip) " +
-        "-i $(location :robolectric_framework_raw_res_orig) " +
-        "-o $(location robolectric_framework_raw_res.jar) " +
-        "-x META-INF/**/* " +
-        "**/*:raw-res/",
-}
-
 java_genrule_host {
     name: "robolectric_framework_res",
     tools: ["zip2zip"],
@@ -115,7 +94,6 @@
         "robolectric_android-all-device-deps",
         "robolectric_tzdata",
         "robolectric_framework_res",
-        "robolectric_framework_raw_res",
     ],
     dist: {
         targets: [
@@ -155,11 +133,11 @@
         "Robolectric_sandbox",
         "Robolectric_junit",
         "Robolectric_utils",
-        "asm-9.2",
+        "ow2-asm",
         "junit",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "guava",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "bouncycastle-unbundled",
         "robolectric-sqlite4java-0.282",
         "hamcrest",
diff --git a/junit/Android.bp b/junit/Android.bp
index 38ab529..bee7514 100644
--- a/junit/Android.bp
+++ b/junit/Android.bp
@@ -18,12 +18,12 @@
         "Robolectric_shadowapi",
         "Robolectric_sandbox",
         "Robolectric_utils",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "hamcrest",
         "junit",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
     ],
     srcs: ["src/main/java/**/*.java"],
diff --git a/processor/Android.bp b/processor/Android.bp
index 7dbdbc0..a61af50 100644
--- a/processor/Android.bp
+++ b/processor/Android.bp
@@ -21,16 +21,17 @@
     static_libs: [
         "Robolectric_annotations",
         "Robolectric_shadowapi",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
-        "asm-tree-9.2",
-        "gson-prebuilt-jar",
-        "asm-9.2",
+        "ow2-asm-tree",
+        "gson",
+        "ow2-asm",
         "jsr305",
     ],
 
     openjdk9: {
         javacflags: [
+            "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
             "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
             "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
         ],
@@ -64,7 +65,7 @@
         "objenesis",
         "junit",
         "truth-prebuilt",
-        "gson-prebuilt-jar",
+        "gson",
         "jsr305",
     ],
 
diff --git a/processor/AndroidTest.xml b/processor/AndroidTest.xml
index 96fc658..7f31410 100644
--- a/processor/AndroidTest.xml
+++ b/processor/AndroidTest.xml
@@ -18,6 +18,8 @@
         <option name="jar" value="Robolectric_processor_tests.jar" />
         <option name="java-flags" value="-Drobolectric.offline=true" />
         <option name="java-flags" value="-Drobolectric.resourcesMode=binary" />
+        <option name="java-flags" value="--add-modules=jdk.compiler"/>
+        <option name="java-flags" value="--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"/>
         <option name="exclude-paths" value="java/" />
     </test>
 </configuration>
diff --git a/processor/sdks.txt b/processor/sdks.txt
index 5444e46..3b4b80d 100644
--- a/processor/sdks.txt
+++ b/processor/sdks.txt
@@ -10,7 +10,8 @@
 prebuilts/misc/common/robolectric/android-all/android-all-8.0.0_r4-robolectric-r1.jar
 prebuilts/misc/common/robolectric/android-all/android-all-8.1.0-robolectric-4611349.jar
 prebuilts/misc/common/robolectric/android-all/android-all-9-robolectric-4913185-2.jar
-prebuilts/misc/common/robolectric/android-all/android-all-9plus-robolectric-5616371.jar
 prebuilts/misc/common/robolectric/android-all/android-all-10-robolectric-5803371.jar
-prebuilts/misc/common/robolectric/android-all/android-all-R-beta2-robolectric-6625208.jar
-prebuilts/misc/common/robolectric/android-all/android-all-S-beta3-robolectric-7541949.jar
+prebuilts/misc/common/robolectric/android-all/android-all-11-robolectric-6757853.jar
+prebuilts/misc/common/robolectric/android-all/android-all-12-robolectric-7732740.jar
+prebuilts/misc/common/robolectric/android-all/android-all-12.1-robolectric-8229987.jar
+prebuilts/misc/common/robolectric/android-all/android-all-13-robolectric-9030017.jar
diff --git a/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java b/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
index 1f11dbb..b1d8cb8 100644
--- a/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
+++ b/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
@@ -5,8 +5,6 @@
 import static org.robolectric.annotation.processing.validator.ImplementsValidator.STATIC_INITIALIZER_METHOD_NAME;
 import static org.robolectric.annotation.processing.validator.ImplementsValidator.getClassFQName;
 
-import com.sun.tools.javac.code.Type.ArrayType;
-import com.sun.tools.javac.code.Type.TypeVar;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -29,7 +27,10 @@
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
@@ -100,10 +101,10 @@
   }
 
   private static String canonicalize(TypeMirror typeMirror) {
-    if (typeMirror instanceof TypeVar) {
-      return ((TypeVar) typeMirror).getUpperBound().toString();
-    } else if (typeMirror instanceof ArrayType) {
-      return canonicalize(((ArrayType) typeMirror).elemtype) + "[]";
+    if (typeMirror.getKind() == TypeKind.TYPEVAR) {
+      return ((TypeVariable) typeMirror).getUpperBound().toString();
+    } else if (typeMirror.getKind() == TypeKind.ARRAY) {
+      return canonicalize(((ArrayType) typeMirror).getComponentType()) + "[]";
     } else {
       return typeMirror.toString();
     }
diff --git a/resources/Android.bp b/resources/Android.bp
index 76c2c05..3d08f90 100644
--- a/resources/Android.bp
+++ b/resources/Android.bp
@@ -20,6 +20,11 @@
         "guava",
         "jsr305",
     ],
+    errorprone: {
+        javacflags: [
+            "-Xep:EmptyTopLevelDeclaration:WARN",
+        ],
+    },
 }
 
 //#############################################
diff --git a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
index 09f7957..0c41714 100644
--- a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
+++ b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
@@ -400,15 +400,17 @@
         // });
         ResTable_sparseTypeEntry result = null;
         for (int i = 0; i < entry_count; i++) {
-          ResTable_sparseTypeEntry entry = new ResTable_sparseTypeEntry(type_chunk.myBuf(),
-              type_chunk.myOffset() + offsets_offset);
-          if (entry.idxOrOffset >= entry_index) {
+            ResTable_sparseTypeEntry entry =
+              new ResTable_sparseTypeEntry(
+                  type_chunk.myBuf(),
+                  type_chunk.myOffset() + offsets_offset + i * ResTable_sparseTypeEntry.SIZEOF);
+          if (entry.idx >= entry_index) {
             result = entry;
             break;
           }
         }
 
-        if (result == null || dtohs(result.idxOrOffset) != entry_index) {
+        if (result == null || dtohs(result.idx) != entry_index) {
           // No entry found.
           return ResTable_type.NO_ENTRY;
         }
@@ -416,7 +418,7 @@
         // Extract the offset from the entry. Each offset must be a multiple of 4 so we store it as
         // the real offset divided by 4.
         // return int{dtohs(result.offset)} * 4u;
-        return dtohs(result.idxOrOffset) * 4;
+        return dtohs(result.offset) * 4;
       }
 
       // This type is encoded as a dense array.
diff --git a/resources/src/main/java/org/robolectric/res/android/ResTable.java b/resources/src/main/java/org/robolectric/res/android/ResTable.java
index dbb2c6f..2176caf 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResTable.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResTable.java
@@ -630,18 +630,18 @@
               sparseIndices,
               new ResTable_sparseTypeEntry(buf, sparseIndices.myOffset() + dtohl(thisType.entryCount)),
               new ResTable_sparseTypeEntry(buf, realEntryIndex),
-              (a, b) -> dtohs(a.idxOrOffset) < dtohs(b.idxOrOffset));
+              (a, b) -> dtohs(a.idx) < dtohs(b.idx));
 //          if (result == sparseIndices + dtohl(thisType.entryCount)
 //              || dtohs(result.idx) != realEntryIndex) {
           if (result.myOffset() == sparseIndices.myOffset() + dtohl(thisType.entryCount)
-              || dtohs(result.idxOrOffset) != realEntryIndex) {
+              || dtohs(result.idx) != realEntryIndex) {
             // No entry found.
             continue;
           }
           // Extract the offset from the entry. Each offset must be a multiple of 4
           // so we store it as the real offset divided by 4.
 //          thisOffset = dtohs(result->offset) * 4u;
-          thisOffset = dtohs(result.idxOrOffset) * 4;
+          thisOffset = dtohs(result.offset) * 4;
         } else {
           if (realEntryIndex >= dtohl(thisType.entryCount)) {
             // Entry does not exist.
@@ -986,11 +986,6 @@
           }
 
           Type t = typeList.get(typeList.size() - 1);
-          if (newEntryCount != t.entryCount) {
-            ALOGE("ResTable_type entry count inconsistent: given %d, previously %d",
-                (int) newEntryCount, (int) t.entryCount);
-            return (mError = BAD_TYPE);
-          }
 
           if (t._package_ != _package) {
             ALOGE("No TypeSpec for type %d", type.id);
diff --git a/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java b/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
index ce12e4b..5438f33 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
@@ -1259,12 +1259,13 @@
    * An entry in a ResTable_type with the flag `FLAG_SPARSE` set.
    */
   static class ResTable_sparseTypeEntry extends WithOffset {
-    public static final int SIZEOF = 6;
+    public static final int SIZEOF = 4;
 
     // Holds the raw uint32_t encoded value. Do not read this.
     int entry;
 
-    short idxOrOffset;
+    short idx;
+    short offset;
 //    struct {
       // The index of the entry.
 //      uint16_t idx;
@@ -1276,8 +1277,8 @@
     public ResTable_sparseTypeEntry(ByteBuffer buf, int offset) {
       super(buf, offset);
 
-      entry = buf.getInt(offset);
-      idxOrOffset = buf.getShort(offset + 4);
+      this.idx = buf.getShort(offset);
+      this.offset = buf.getShort(offset + 2);
     }
   };
 
diff --git a/robolectric/Android.bp b/robolectric/Android.bp
index ab08b47..4d2639d 100644
--- a/robolectric/Android.bp
+++ b/robolectric/Android.bp
@@ -25,13 +25,13 @@
         "robolectric-host-androidx-test-monitor",
         "robolectric-maven-ant-tasks-2.1.3",
         "bouncycastle-unbundled",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
         "robolectric-xstream-1.4.8",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "junit",
         "robolectric-ant-1.8.0",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
         "robolectric-host-android_all",
     ],
@@ -70,17 +70,17 @@
         "bouncycastle-unbundled",
         "hamcrest",
         "robolectric-sqlite4java-0.282",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "robolectric-diffutils-1.3.0",
         "guava",
         "objenesis",
         "robolectric-xstream-1.4.8",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "junit",
         "icu4j",
         "truth-prebuilt",
         "robolectric-ant-1.8.0",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
     ],
     libs: ["robolectric-host-android_all"],
@@ -88,4 +88,10 @@
     test_options: {
         unit_test: false,
     },
+
+    errorprone: {
+        javacflags: [
+            "-Xep:ReturnValueIgnored:WARN",
+        ],
+    },
 }
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java b/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java
index a3119e0..d44a05f 100644
--- a/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java
@@ -29,6 +29,8 @@
 
   @Nullable private ActivityController<? extends Activity> controller;
 
+  private boolean isActivityLaunchedForResult = false;
+
   @Override
   public void startActivity(Intent intent, @Nullable Bundle activityOptions) {
     startActivity(intent);
@@ -54,7 +56,23 @@
   }
 
   @Override
+  public void startActivityForResult(Intent intent, @Nullable Bundle activityOptions) {
+   startActivityForResult(intent);
+  }
+
+  @Override
+  public void startActivityForResult(Intent intent) {
+    isActivityLaunchedForResult = true;
+    startActivity(intent);
+  }
+
+  @Override
   public ActivityResult getActivityResult() {
+    if (!isActivityLaunchedForResult) {
+      throw new IllegalStateException(
+          "You must start Activity first. Make sure you are using launchActivityForResult() to"
+          + " launch an Activity.");
+    }
     checkNotNull(controller);
     checkState(controller.get().isFinishing(), "You must finish your Activity first");
     ShadowActivity shadowActivity = Shadow.extract(controller.get());
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java b/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
index e74a03c..5de0488 100644
--- a/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
@@ -420,7 +420,8 @@
    * Create a file system safe directory path name for the current test.
    */
   private String createTestDataDirRootPath(Method method) {
-    return method.getClass().getSimpleName() + "_" + method.getName().replaceAll("[^a-zA-Z0-9.-]", "_");
+    return method.getDeclaringClass().getSimpleName() + "_" +
+        method.getName().replaceAll("[^a-zA-Z0-9.-]", "_");
   }
 
   @Override
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
index bde0e72..f9721e4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
@@ -1,6 +1,6 @@
 package org.robolectric.shadows;
 
-import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 import static com.google.common.truth.Truth.assertThat;
 
 import android.icu.text.DateFormat;
@@ -12,13 +12,13 @@
 import java.text.ParseException;
 import java.util.Calendar;
 import java.util.Date;
-import libcore.icu.DateIntervalFormat;
+import android.text.format.DateIntervalFormat;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
 @RunWith(AndroidJUnit4.class)
-@Config(minSdk = M)
+@Config(minSdk = UPSIDE_DOWN_CAKE)
 public class ShadowDateIntervalFormatTest {
   @Test
   public void testDateInterval_FormatDateRange() throws ParseException {
diff --git a/robotest-internal.mk b/robotest-internal.mk
index 77e1730..34db668 100644
--- a/robotest-internal.mk
+++ b/robotest-internal.mk
@@ -25,7 +25,7 @@
 $(my_target_output): PRIVATE_TESTS := $(my_tests)
 $(my_target_output): PRIVATE_JARS := $(my_jars)
 $(my_target_output): PRIVATE_JAVA_ARGS := $(my_java_args)
-$(my_target_output): PRIVATE_JAVA_PATH := $(ANDROID_JAVA11_HOME)/bin:
+$(my_target_output): PRIVATE_JAVA_PATH := $(ANDROID_JAVA17_HOME)/bin:
 $(my_target_output): PRIVATE_ROBOLECTRIC_PATH := $(my_robolectric_path)
 $(my_target_output): PRIVATE_ROBOLECTRIC_SCRIPT_PATH := $(my_robolectric_script_path)
 $(my_target_output): PRIVATE_TARGET_MESSAGE := $(my_target_message)
diff --git a/robotest.sh b/robotest.sh
index e95f09d..df5570b 100755
--- a/robotest.sh
+++ b/robotest.sh
@@ -73,6 +73,8 @@
     # Remove the timeout so Robolectric doesn't get killed while debugging
     local debug_timeout="0"
   fi
+  # For --add-opens jdk.internal.util.random see b/238100560.
+  # For --add-opens java.io see b/251387255.
   local command=(
     "${PRIVATE_ROBOLECTRIC_SCRIPT_PATH}/java-timeout"
     "${debug_timeout:-${PRIVATE_TIMEOUT}}"
@@ -84,6 +86,10 @@
     -Drobolectric.conscryptMode=OFF
     -Drobolectric.logging.enabled=true
     -cp "$classpath"
+    --add-opens=java.base/java.lang=ALL-UNNAMED
+    --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+    --add-opens=java.base/jdk.internal.util.random=ALL-UNNAMED
+    --add-opens=java.base/java.io=ALL-UNNAMED
     com.android.junitxml.JUnitXmlRunner
   )
   echo "${command[@]}" "$@"
diff --git a/run_robolectric_module_tests.mk b/run_robolectric_module_tests.mk
index 96f1cb5..0050c73 100644
--- a/run_robolectric_module_tests.mk
+++ b/run_robolectric_module_tests.mk
@@ -51,9 +51,11 @@
   $(android_all_source_dir)/android-all-8.0.0_r4-robolectric-r1.jar:$(android_all_target_dir)/android-all-8.0.0_r4-robolectric-r1.jar \
   $(android_all_source_dir)/android-all-8.1.0-robolectric-4611349.jar:$(android_all_target_dir)/android-all-8.1.0-robolectric-4611349.jar \
   $(android_all_source_dir)/android-all-9-robolectric-4913185-2.jar:$(android_all_target_dir)/android-all-9-robolectric-4913185-2.jar \
-  $(android_all_source_dir)/android-all-9plus-robolectric-5616371.jar:$(android_all_target_dir)/android-all-9plus-robolectric-5616371.jar \
-  $(android_all_source_dir)/android-all-R-beta2-robolectric-6625208.jar:$(android_all_target_dir)/android-all-R-beta2-robolectric-6625208.jar \
-  $(android_all_source_dir)/android-all-S-beta3-robolectric-7541949.jar:$(android_all_target_dir)/android-all-S-beta3-robolectric-7541949.jar \
+  $(android_all_source_dir)/android-all-10-robolectric-5803371.jar:$(android_all_target_dir)/android-all-10-robolectric-5803371.jar \
+  $(android_all_source_dir)/android-all-11-robolectric-6757853.jar:$(android_all_target_dir)/android-all-11-robolectric-6757853.jar \
+  $(android_all_source_dir)/android-all-12-robolectric-7732740.jar:$(android_all_target_dir)/android-all-12-robolectric-7732740.jar \
+  $(android_all_source_dir)/android-all-12.1-robolectric-8229987.jar:$(android_all_target_dir)/android-all-12.1-robolectric-8229987.jar \
+  $(android_all_source_dir)/android-all-13-robolectric-9030017.jar:$(android_all_target_dir)/android-all-13-robolectric-9030017.jar \
   $(local_android_all_source_jar):$(android_all_target_dir)/android-all-current-robolectric-r0.jar
 copy_android_all_jars := $(call copy-many-files, $(copy_android_all_jar_pairs))
 
@@ -91,6 +93,9 @@
 	  -Drobolectric.resourcesMode=binary \
 	  -Drobolectric-tests.base-dir=$(private_test_base_dir) \
 	  -Drobolectric.dependency.dir=$(private_android_all_dir) \
+	  --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
+	  --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
+	  --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
 	  $(private_debug_test_args) \
 	  -cp $(private_host_jdk_tools_jar):$(private_test_base_dir):$(private_classpath_jars) \
 	  org.junit.runner.JUnitCore \
diff --git a/run_robotests.mk b/run_robotests.mk
index b5a6ee4..cb0db1b 100644
--- a/run_robotests.mk
+++ b/run_robotests.mk
@@ -135,8 +135,10 @@
       $(android_all_lib_path)/android-all-8.1.0-robolectric-4611349.jar:$(my_robolectric_path)/android-all-8.1.0-robolectric-4611349.jar \
       $(android_all_lib_path)/android-all-9-robolectric-4913185-2.jar:$(my_robolectric_path)/android-all-9-robolectric-4913185-2.jar \
       $(android_all_lib_path)/android-all-10-robolectric-5803371.jar:$(my_robolectric_path)/android-all-10-robolectric-5803371.jar \
-      $(android_all_lib_path)/android-all-R-beta2-robolectric-6625208.jar:$(my_robolectric_path)/android-all-R-beta2-robolectric-6625208.jar \
-      $(android_all_lib_path)/android-all-S-beta3-robolectric-7541949.jar:$(my_robolectric_path)/android-all-S-beta3-robolectric-7541949.jar \
+      $(android_all_lib_path)/android-all-11-robolectric-6757853.jar:$(my_robolectric_path)/android-all-11-robolectric-6757853.jar \
+      $(android_all_lib_path)/android-all-12-robolectric-7732740.jar:$(my_robolectric_path)/android-all-12-robolectric-7732740.jar \
+      $(android_all_lib_path)/android-all-12.1-robolectric-8229987.jar:$(my_robolectric_path)/android-all-12.1-robolectric-8229987.jar \
+      $(android_all_lib_path)/android-all-13-robolectric-9030017.jar:$(my_robolectric_path)/android-all-13-robolectric-9030017.jar \
       $(local_android_all_source_jar):$(my_robolectric_path)/android-all-current-robolectric-r0.jar
     copy_android_all_jars := $(call copy-many-files, $(copy_android_all_jar_pairs))
 
diff --git a/sandbox/Android.bp b/sandbox/Android.bp
index ae6aa36..fafcdef 100644
--- a/sandbox/Android.bp
+++ b/sandbox/Android.bp
@@ -18,10 +18,10 @@
         "Robolectric_annotations",
         "Robolectric_shadowapi",
         "Robolectric_utils",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
-        "asm-tree-9.2",
-        "asm-9.2",
+        "ow2-asm-tree",
+        "ow2-asm",
         "jsr305",
     ],
 }
@@ -41,14 +41,19 @@
         "Robolectric_utils",
         "mockito",
         "hamcrest",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
         "objenesis",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "junit",
         "truth-prebuilt",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
     ],
     test_suites: ["general-tests"],
+    errorprone: {
+        javacflags: [
+            "-Xep:ReturnValueIgnored:WARN",
+        ],
+    },
 }
diff --git a/sandbox/AndroidTest.xml b/sandbox/AndroidTest.xml
index 932f083..f8f3c87 100644
--- a/sandbox/AndroidTest.xml
+++ b/sandbox/AndroidTest.xml
@@ -18,6 +18,7 @@
         <option name="jar" value="Robolectric_sandbox_tests.jar" />
         <option name="java-flags" value="-Drobolectric.offline=true" />
         <option name="java-flags" value="-Drobolectric.resourcesMode=binary" />
+        <option name="java-flags" value="--add-opens=java.base/java.lang=ALL-UNNAMED"/>
         <option name="exclude-paths" value="java/" />
     </test>
 </configuration>
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
index 8997be4..ebe36c6 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
@@ -42,7 +42,7 @@
       final InstrumentationConfiguration config,
       ClassNodeProvider classNodeProvider) {
     ClassNode classNode =
-        new ClassNode(Opcodes.ASM4) {
+        new ClassNode(Opcodes.ASM9) {
           @Override
           public FieldVisitor visitField(
               int access, String name, String desc, String signature, Object value) {
@@ -366,7 +366,7 @@
 
   //todo rename
   private MethodNode redirectorMethod(MutableClass mutableClass, MethodNode method, String newName) {
-    MethodNode redirector = new MethodNode(Opcodes.ASM4, newName, method.desc, method.signature, exceptionArray(method));
+    MethodNode redirector = new MethodNode(Opcodes.ASM9, newName, method.desc, method.signature, exceptionArray(method));
     redirector.access = method.access & ~(Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL);
     makeMethodPrivate(redirector);
     RobolectricGeneratorAdapter generator = new RobolectricGeneratorAdapter(redirector);
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ProxyMaker.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ProxyMaker.java
index 9cf0c82..67dbdf2 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ProxyMaker.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ProxyMaker.java
@@ -6,6 +6,9 @@
 import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
 import static org.objectweb.asm.Opcodes.V1_7;
 
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import org.objectweb.asm.ClassWriter;
@@ -16,18 +19,68 @@
 
 public class ProxyMaker {
   private static final String TARGET_FIELD = "__proxy__";
+  private static final Class UNSAFE_CLASS = Unsafe.class;
+  private static final Class LOOKUP_CLASS = MethodHandles.Lookup.class;
   private static final Unsafe UNSAFE;
 
+  private static final java.lang.reflect.Method DEFINE_ANONYMOUS_CLASS;
+
+  private static final MethodHandles.Lookup LOOKUP;
+  private static final java.lang.reflect.Method HIDDEN_DEFINE_METHOD;
+  private static final Object HIDDEN_CLASS_OPTIONS;
+
   static {
     try {
-      Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+      Field unsafeField = UNSAFE_CLASS.getDeclaredField("theUnsafe");
       unsafeField.setAccessible(true);
       UNSAFE = (Unsafe) unsafeField.get(null);
-    } catch (NoSuchFieldException | IllegalAccessException e) {
+
+      // Unsafe.defineAnonymousClass() has been deprecated in Java 15 and removed in Java 17. Its
+      // usage should be replace by MethodHandles.Lookup.defineHiddenClass() which was introduced in
+      // Java 15. For now, try and support both older and newer Java versions.
+      DEFINE_ANONYMOUS_CLASS = getDefineAnonymousClass();
+      if (DEFINE_ANONYMOUS_CLASS == null) {
+        LOOKUP = getTrustedLookup();
+
+        Class classOptionClass = Class.forName(LOOKUP_CLASS.getName() + "$ClassOption");
+        HIDDEN_CLASS_OPTIONS = Array.newInstance(classOptionClass, 1);
+        Array.set(HIDDEN_CLASS_OPTIONS, 0, Enum.valueOf(classOptionClass, "NESTMATE"));
+        HIDDEN_DEFINE_METHOD = LOOKUP_CLASS.getMethod("defineHiddenClass", byte[].class,
+                                                      boolean.class,
+                                                      HIDDEN_CLASS_OPTIONS.getClass());
+      } else {
+        LOOKUP = null;
+        HIDDEN_DEFINE_METHOD = null;
+        HIDDEN_CLASS_OPTIONS = null;
+      }
+    } catch (ReflectiveOperationException e) {
       throw new AssertionError(e);
     }
   }
 
+  private static java.lang.reflect.Method getDefineAnonymousClass() {
+      try {
+        return UNSAFE_CLASS.getMethod("defineAnonymousClass", Class.class,
+                                                       byte[].class, Object[].class);
+      } catch (NoSuchMethodException e) {
+        return null;
+      }
+  }
+
+  private static MethodHandles.Lookup getTrustedLookup() throws ReflectiveOperationException {
+    Field trustedLookupField = LOOKUP_CLASS.getDeclaredField("IMPL_LOOKUP");
+    java.lang.reflect.Method baseMethod = UNSAFE_CLASS.getMethod("staticFieldBase",
+                                                                 Field.class);
+    Object lookupBase = baseMethod.invoke(UNSAFE, trustedLookupField);
+    java.lang.reflect.Method offsetMethod = UNSAFE_CLASS.getMethod("staticFieldOffset",
+                                                                   Field.class);
+    Object lookupOffset = offsetMethod.invoke(UNSAFE, trustedLookupField);
+
+    java.lang.reflect.Method getObjectMethod = UNSAFE_CLASS.getMethod("getObject",
+                                                                      Object.class, long.class);
+    return (MethodHandles.Lookup) getObjectMethod.invoke(UNSAFE, lookupBase, lookupOffset);
+  }
+
   private final MethodMapper methodMapper;
   private final ClassValueMap<Factory> factories;
 
@@ -74,9 +127,8 @@
 
     writer.visitEnd();
 
-    final Class<?> proxyClass = UNSAFE.defineAnonymousClass(targetClass, writer.toByteArray(), null);
-
     try {
+      final Class<?> proxyClass = defineHiddenClass(targetClass, writer.toByteArray());
       final Field field = proxyClass.getDeclaredField(TARGET_FIELD);
       return new Factory() {
         @Override public <E> E createProxy(Class<E> targetClass, E target) {
@@ -91,11 +143,24 @@
           }
         }
       };
-    } catch (NoSuchFieldException e) {
+    } catch (ReflectiveOperationException e) {
       throw new AssertionError(e);
     }
   }
 
+  private static Class<?> defineHiddenClass(Class<?> targetClass,
+                                            byte[] bytes) throws ReflectiveOperationException {
+    if (DEFINE_ANONYMOUS_CLASS != null) {
+        return (Class<?>) DEFINE_ANONYMOUS_CLASS.invoke(UNSAFE, targetClass,
+                                                        bytes, (Object[]) null);
+    } else {
+      MethodHandles.Lookup lookup = (MethodHandles.Lookup) LOOKUP.in(targetClass);
+      MethodHandles.Lookup definedLookup = (MethodHandles.Lookup)
+        HIDDEN_DEFINE_METHOD.invoke(lookup, bytes, false, HIDDEN_CLASS_OPTIONS);
+      return definedLookup.lookupClass();
+    }
+  }
+
   private static boolean shouldProxy(java.lang.reflect.Method method) {
     int modifiers = method.getModifiers();
     return !Modifier.isAbstract(modifiers) && !Modifier.isFinal(modifiers) && !Modifier.isPrivate(
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/RobolectricGeneratorAdapter.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/RobolectricGeneratorAdapter.java
index 1569c37..14ab041 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/RobolectricGeneratorAdapter.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/RobolectricGeneratorAdapter.java
@@ -18,7 +18,7 @@
   private final String desc;
 
   public RobolectricGeneratorAdapter(MethodNode methodNode) {
-    super(Opcodes.ASM4, methodNode, methodNode.access, methodNode.name, methodNode.desc);
+    super(Opcodes.ASM9, methodNode, methodNode.access, methodNode.name, methodNode.desc);
     this.isStatic = Modifier.isStatic(methodNode.access);
     this.desc = methodNode.desc;
   }
diff --git a/shadowapi/Android.bp b/shadowapi/Android.bp
index ad3841e..a46f8ca 100644
--- a/shadowapi/Android.bp
+++ b/shadowapi/Android.bp
@@ -15,6 +15,11 @@
     name: "Robolectric_shadowapi",
     libs: ["jsr305"],
     srcs: ["src/main/java/**/*.java"],
+    openjdk9: {
+        javacflags: [
+            "--add-opens=java.base/java.lang=ALL-UNNAMED",
+        ],
+    },
 }
 
 //#############################################
diff --git a/shadowapi/AndroidTest.xml b/shadowapi/AndroidTest.xml
index 16368dd..c0ef7ca 100644
--- a/shadowapi/AndroidTest.xml
+++ b/shadowapi/AndroidTest.xml
@@ -18,6 +18,8 @@
         <option name="jar" value="Robolectric_shadowapi_tests.jar" />
         <option name="java-flags" value="-Drobolectric.offline=true" />
         <option name="java-flags" value="-Drobolectric.resourcesMode=binary" />
+        <option name="java-flags" value="--add-opens=java.base/java.lang=ALL-UNNAMED"/>
+        <option name="java-flags" value="--add-opens=java.base/java.lang.reflect=ALL-UNNAMED"/>
         <option name="exclude-paths" value="java/" />
     </test>
 </configuration>
diff --git a/shadowapi/src/main/java/org/robolectric/shadow/api/Shadow.java b/shadowapi/src/main/java/org/robolectric/shadow/api/Shadow.java
index 0ae7c85..0d54e52 100644
--- a/shadowapi/src/main/java/org/robolectric/shadow/api/Shadow.java
+++ b/shadowapi/src/main/java/org/robolectric/shadow/api/Shadow.java
@@ -5,7 +5,7 @@
 
 public class Shadow {
   @SuppressWarnings("unused")
-  private final static IShadow SHADOW_IMPL;
+  private static IShadow SHADOW_IMPL;
 
   static {
     try {
diff --git a/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java b/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
index 8fdfdcb..1c2e52d 100644
--- a/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
+++ b/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
@@ -411,20 +411,39 @@
 
   private static void makeFieldVeryAccessible(Field field) {
     field.setAccessible(true);
-
-    try {
-      Field modifiersField = Field.class.getDeclaredField("modifiers");
+    // remove 'final' modifier if present
+    if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
+      Field modifiersField = getModifiersField();
       modifiersField.setAccessible(true);
       try {
         modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
       } catch (IllegalAccessException e) {
-        throw new RuntimeException(e);
+
+        throw new AssertionError(e);
       }
-    } catch (NoSuchFieldException e) {
-      // ignore missing fields
     }
   }
 
+  private static Field getModifiersField() {
+    try {
+      return Field.class.getDeclaredField("modifiers");
+    } catch (NoSuchFieldException e) {
+      try {
+        Method getFieldsMethod = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
+        getFieldsMethod.setAccessible(true);
+        Field[] fields = (Field[]) getFieldsMethod.invoke(Field.class, false);
+        for (Field modifiersField : fields) {
+          if ("modifiers".equals(modifiersField.getName())) {
+            return modifiersField;
+          }
+        }
+      } catch (ReflectiveOperationException innerE) {
+        throw new AssertionError(innerE);
+      }
+    }
+    throw new AssertionError();
+  }
+
   public static Object defaultValueForType(String returnType) {
     return PRIMITIVE_RETURN_VALUES.get(returnType);
   }
diff --git a/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java b/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
index 40c007f..96306d4 100644
--- a/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
+++ b/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
@@ -84,6 +84,19 @@
   }
 
   @Test
+  public void getFinalStaticFieldReflectively_withField_getsStaticField() throws Exception {
+    Field field = ExampleBase.class.getDeclaredField("BASE");
+
+    int result = ReflectionHelpers.getStaticField(field);
+    assertThat(result).isEqualTo(8);
+  }
+
+  @Test
+  public void getFinalStaticFieldReflectively_withFieldName_getsStaticField() throws Exception {
+    assertThat((int) ReflectionHelpers.getStaticField(ExampleBase.class, "BASE")).isEqualTo(8);
+  }
+
+  @Test
   public void setStaticFieldReflectively_withField_setsStaticFields() throws Exception {
     Field field = ExampleDescendant.class.getDeclaredField("DESCENDANT");
     int startingValue = ReflectionHelpers.getStaticField(field);
@@ -109,6 +122,20 @@
   }
 
   @Test
+  public void setFinalStaticFieldReflectively_withFieldName_setsStaticFields() {
+    int startingValue = ReflectionHelpers.getStaticField(ExampleWithFinalStatic.class, "FIELD");
+
+    ReflectionHelpers.setStaticField(ExampleWithFinalStatic.class, "FIELD", 101);
+    assertWithMessage("startingValue").that(startingValue).isEqualTo(100);
+    assertWithMessage("BASE")
+        .that((int) ReflectionHelpers.getStaticField(ExampleWithFinalStatic.class, "FIELD"))
+        .isEqualTo(101);
+
+    // Reset the value to avoid test pollution
+    ReflectionHelpers.setStaticField(ExampleWithFinalStatic.class, "FIELD", startingValue);
+  }
+
+  @Test
   public void callInstanceMethodReflectively_callsPrivateMethods() {
     ExampleDescendant example = new ExampleDescendant();
     assertThat((int) ReflectionHelpers.callInstanceMethod(example, "returnNumber")).isEqualTo(1337);
@@ -339,6 +366,11 @@
     }
   }
 
+  @SuppressWarnings("unused")
+  private static class ExampleWithFinalStatic {
+    private static final int FIELD = 100;
+  }
+
   private static class ThrowsError {
     @SuppressWarnings("unused")
     public ThrowsError() {
diff --git a/shadows/framework/Android.bp b/shadows/framework/Android.bp
index 28a7108..2eddf8b 100644
--- a/shadows/framework/Android.bp
+++ b/shadows/framework/Android.bp
@@ -32,4 +32,11 @@
     javacflags: ["-Aorg.robolectric.annotation.processing.shadowPackage=org.robolectric"],
     srcs: ["src/main/java/**/*.java"],
     java_resource_dirs: ["src/main/resources"],
+    errorprone: {
+        javacflags: [
+            "-Xep:XorPower:WARN",
+            "-Xep:EmptyTopLevelDeclaration:WARN",
+            "-Xep:ReturnValueIgnored:WARN",
+        ],
+    },
 }
diff --git a/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java b/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
index 3f173dc..b41ca9c 100644
--- a/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
+++ b/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
@@ -16,6 +16,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.ViewRootImpl;
 import org.robolectric.RuntimeEnvironment;
@@ -160,9 +161,14 @@
       callDispatchResized(root);
     }
 
-    ReflectionHelpers.callInstanceMethod(root, "windowFocusChanged",
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+      ReflectionHelpers.callInstanceMethod(root, "windowFocusChanged",
+        from(boolean.class, hasFocus));
+    } else {
+      ReflectionHelpers.callInstanceMethod(root, "windowFocusChanged",
         from(boolean.class, hasFocus), /* hasFocus */
         from(boolean.class, false) /* inTouchMode */);
+    }
     return this;
   }
 
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ImageUtil.java b/shadows/framework/src/main/java/org/robolectric/shadows/ImageUtil.java
index 534a0ee..83ed5a7 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ImageUtil.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ImageUtil.java
@@ -21,7 +21,25 @@
 public class ImageUtil {
   private static boolean initialized;
 
+  public static class ImageInfo {
+
+    public final int width;
+    public final int height;
+    public final String mimeType;
+
+    ImageInfo(int width, int height, String mimeType) {
+      this.width = width;
+      this.height = height;
+      this.mimeType = mimeType;
+    }
+  }
+
   public static Point getImageSizeFromStream(InputStream is) {
+    ImageInfo info = getImageInfoFromStream(is);
+    return new Point(info.width, info.height);
+  }
+
+  public static ImageInfo getImageInfoFromStream(InputStream is) {
     if (!initialized) {
       // Stops ImageIO from creating temp files when reading images
       // from input stream.
@@ -37,7 +55,7 @@
       ImageReader reader = readers.next();
       try {
         reader.setInput(imageStream);
-        return new Point(reader.getWidth(0), reader.getHeight(0));
+        return new ImageInfo(reader.getWidth(0), reader.getHeight(0), "image/" + reader.getFormatName());
       } finally {
         reader.dispose();
       }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
index bea306d..0ec2bc8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
@@ -5,6 +5,7 @@
 import static android.os.Build.VERSION_CODES.LOLLIPOP;
 import static android.os.Build.VERSION_CODES.M;
 import static android.os.Build.VERSION_CODES.N;
+import static android.os.Build.VERSION_CODES.S;
 
 import android.annotation.TargetApi;
 import android.app.AlarmManager;
@@ -29,6 +30,7 @@
 
   private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault();
 
+  private static boolean canScheduleExactAlarms;
   private final List<ScheduledAlarm> scheduledAlarms = new ArrayList<>();
 
   @RealObject private AlarmManager realObject;
@@ -36,6 +38,7 @@
   @Resetter
   public static void reset() {
     TimeZone.setDefault(DEFAULT_TIMEZONE);
+    canScheduleExactAlarms = false;
   }
 
   @Implementation
@@ -196,6 +199,20 @@
     }
   }
 
+  /** Returns the schedule exact alarm state set by {@link #setCanScheduleExactAlarms}. */
+  @Implementation(minSdk = S)
+  protected boolean canScheduleExactAlarms() {
+    return canScheduleExactAlarms;
+  }
+
+  /**
+   * Sets the schedule exact alarm state reported by {@link AlarmManager#canScheduleExactAlarms},
+   * but has no effect otherwise.
+   */
+  public static void setCanScheduleExactAlarms(boolean scheduleExactAlarms) {
+    canScheduleExactAlarms = scheduleExactAlarms;
+  }
+
   /**
    * Container object to hold a PendingIntent and parameters describing when to send it.
    */
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormat.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormat.java
index abbed64..83d5235 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormat.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormat.java
@@ -2,16 +2,17 @@
 
 import static android.os.Build.VERSION_CODES.KITKAT;
 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
+import static android.os.Build.VERSION_CODES.TIRAMISU;
 
 import java.text.FieldPosition;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
-import libcore.icu.DateIntervalFormat;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 
-@Implements(value = DateIntervalFormat.class, isInAndroidSdk = false, minSdk = KITKAT)
+@Implements(className = "libcore.icu.DateIntervalFormat", isInAndroidSdk = false, minSdk = KITKAT,
+        maxSdk = TIRAMISU)
 public class ShadowDateIntervalFormat {
 
   private static long address;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormatU.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormatU.java
new file mode 100644
index 0000000..ac435c4
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateIntervalFormatU.java
@@ -0,0 +1,42 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
+import java.text.FieldPosition;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import android.text.format.DateIntervalFormat;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = DateIntervalFormat.class, isInAndroidSdk = false, minSdk = UPSIDE_DOWN_CAKE)
+public class ShadowDateIntervalFormatU {
+
+  private static long address;
+  private static Map<Long, com.ibm.icu.text.DateIntervalFormat> INTERVAL_CACHE = new HashMap<>();
+
+  @Implementation
+  public static long createDateIntervalFormat(String skeleton, String localeName, String tzName) {
+    address++;
+    INTERVAL_CACHE.put(address, com.ibm.icu.text.DateIntervalFormat.getInstance(skeleton, new Locale(localeName)));
+    return address;
+  }
+
+  @Implementation
+  public static void destroyDateIntervalFormat(long address) {
+    INTERVAL_CACHE.remove(address);
+  }
+
+  @Implementation
+  @SuppressWarnings("JdkObsolete")
+  public static String formatDateInterval(long address, long fromDate, long toDate) {
+    StringBuffer buffer = new StringBuffer();
+
+    FieldPosition pos = new FieldPosition(0);
+    INTERVAL_CACHE.get(address).format(new com.ibm.icu.util.DateInterval(fromDate, toDate), buffer, pos);
+
+    return buffer.toString();
+  }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
index fbe48ac..b7efad5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
@@ -39,12 +39,14 @@
     private final int height;
     private final boolean animated = false;
     private final boolean ninePatch;
+    private final String mimeType;
 
     ImgStream() {
       InputStream inputStream = getInputStream();
-      final Point size = ImageUtil.getImageSizeFromStream(inputStream);
-      this.width = size == null ? 10 : size.x;
-      this.height = size == null ? 10 : size.y;
+      final ImageUtil.ImageInfo info = ImageUtil.getImageInfoFromStream(inputStream);
+      this.width = info == null ? 10 : info.width;
+      this.height = info == null ? 10 : info.height;
+      this.mimeType = info == null ? "" : info.mimeType;
       if (inputStream instanceof AssetManager.AssetInputStream) {
         ShadowAssetInputStream sis = Shadow.extract(inputStream);
         this.ninePatch = sis.isNinePatch();
@@ -70,6 +72,10 @@
     boolean isNinePatch() {
       return ninePatch;
     }
+
+    String getMimeType() {
+      return mimeType;
+    }
   }
 
   private static final class CppImageDecoder {
@@ -80,6 +86,9 @@
       this.imgStream = imgStream;
     }
 
+    public String getMimeType() {
+      return imgStream.getMimeType();
+    }
   }
 
   private static final NativeObjRegistry<CppImageDecoder> NATIVE_IMAGE_DECODER_REGISTRY =
@@ -238,8 +247,7 @@
 
   static String ImageDecoder_nGetMimeType(long nativePtr) {
     CppImageDecoder decoder = NATIVE_IMAGE_DECODER_REGISTRY.getNativeObject(nativePtr);
-    // return encodedFormatToString(decoder.mCodec.getEncodedFormat());
-    throw new UnsupportedOperationException();
+    return decoder.getMimeType();
   }
 
   static ColorSpace ImageDecoder_nGetColorSpace(long nativePtr) {
@@ -247,7 +255,7 @@
     // auto colorType = codec.computeOutputColorType(codec.getInfo().colorType());
     // sk_sp<SkColorSpace> colorSpace = codec.computeOutputColorSpace(colorType);
     // return GraphicsJNI.getColorSpace(colorSpace, colorType);
-    throw new UnsupportedOperationException();
+    return null;
   }
 
 
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
index 4c8ebf5..867c720 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
@@ -3,6 +3,7 @@
 import static android.os.Build.VERSION_CODES.KITKAT;
 
 import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
 import android.view.InputEvent;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
@@ -25,6 +26,7 @@
 
   @Resetter
   public static void reset() {
-    ReflectionHelpers.setStaticField(InputManager.class, "sInstance", null);
+    ReflectionHelpers.setStaticField(InputManagerGlobal.class,
+            "sInstance", null);
   }
 }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteConnection.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteConnection.java
index d4b8a1d..ce65e8e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteConnection.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteConnection.java
@@ -1,5 +1,6 @@
 package org.robolectric.shadows;
 
+import static android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
 import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
 import static android.os.Build.VERSION_CODES.LOLLIPOP;
 import static android.os.Build.VERSION_CODES.O;
@@ -158,11 +159,16 @@
     nativeExecute((long) connectionPtr, (long) statementPtr);
   }
 
-  @Implementation(minSdk = LOLLIPOP)
+  @Implementation(minSdk = LOLLIPOP, maxSdk = 32)
   public static void nativeExecute(final long connectionPtr, final long statementPtr) {
     CONNECTIONS.executeStatement(connectionPtr, statementPtr);
   }
 
+  @Implementation(minSdk = CUR_DEVELOPMENT)
+  public static void nativeExecute(final long connectionPtr, final long statementPtr, boolean isPragmaStmt){
+    CONNECTIONS.executeStatement(connectionPtr, statementPtr);
+  }
+
   @Implementation(maxSdk = KITKAT_WATCH)
   public static String nativeExecuteForString(int connectionPtr, int statementPtr) {
     return nativeExecuteForString((long) connectionPtr, (long) statementPtr);
@@ -668,7 +674,7 @@
         @Override
         public Long call() throws Exception {
           statement.stepThrough();
-          return connection.getLastInsertId();
+          return connection.getChanges() > 0 ? connection.getLastInsertId() : -1L;
         }
       });
     }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
index c37ca3a..00fea94 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
@@ -1,27 +1,51 @@
 package org.robolectric.shadows;
 
-
 import android.hardware.Sensor;
 import android.os.Build.VERSION_CODES;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
 import org.robolectric.shadow.api.Shadow;
 import org.robolectric.util.ReflectionHelpers;
-import org.robolectric.util.ReflectionHelpers.ClassParameter;
 
 @Implements(Sensor.class)
 public class ShadowSensor {
 
-  /**
-   * Constructs a {@link Sensor} with a given type.
-   */
+  @RealObject private Sensor realSensor;
+
+  /** Constructs a {@link Sensor} with a given type. */
   public static Sensor newInstance(int type) {
     Sensor sensor = Shadow.newInstanceOf(Sensor.class);
     if (RuntimeEnvironment.getApiLevel() >= VERSION_CODES.M) {
-      Shadow.directlyOn(sensor, Sensor.class, "setType", ClassParameter.from(int.class, type));
+      Shadow.directlyOn(sensor, Sensor.class, "setType", ReflectionHelpers.ClassParameter.from(int.class, type));
     } else {
       ReflectionHelpers.setField(Sensor.class, sensor, "mType", type);
     }
     return sensor;
   }
+
+  /** Controls the return value of {@link Sensor#isWakeUpSensor()}. */
+  public void setWakeUpFlag(boolean wakeup) {
+    int wakeUpSensorFlag = getWakeUpSensorFlag();
+
+    if(wakeup) {
+      setMask(wakeUpSensorFlag);
+    } else {
+      clearMask(wakeUpSensorFlag);
+    }
+  }
+
+  private void setMask(int mask) {
+    int value = ReflectionHelpers.getField(realSensor, "mFlags");
+    ReflectionHelpers.setField(realSensor, "mFlags", (value | mask));
+  }
+
+  private void clearMask(int mask) {
+    int value = ReflectionHelpers.getField(realSensor, "mFlags");
+    ReflectionHelpers.setField(realSensor, "mFlags", (value & ~mask));
+  }
+
+  private int getWakeUpSensorFlag() {
+    return ReflectionHelpers.getStaticField(Sensor.class, "SENSOR_FLAG_WAKE_UP_SENSOR");
+  }
 }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
index 68a80cd..05a4b95 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
@@ -53,6 +53,12 @@
     return sensorMap.get(type);
   }
 
+  @Implementation
+  protected Sensor getDefaultSensor(int type, boolean wakeUp) {
+    Sensor typedSensor = sensorMap.get(type);
+    return (typedSensor != null && typedSensor.isWakeUpSensor() == wakeUp) ? typedSensor : null;
+  }
+
   /** @param handler is ignored. */
   @Implementation
   protected boolean registerListener(
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
index 3c4afda..facd5a5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
@@ -55,6 +55,7 @@
 import android.os.storage.IStorageManager;
 import android.permission.IPermissionManager;
 import android.service.persistentdata.IPersistentDataBlockService;
+import android.view.IWindowManager;
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
@@ -133,6 +134,9 @@
     map.put(
         Context.APPWIDGET_SERVICE,
         createBinder(IAppWidgetService.class, "com.android.internal.appwidget.IAppWidgetService"));
+    map.put(
+            Context.WINDOW_SERVICE,
+            createBinder(IWindowManager.class, "android.view.IWindowManager"));
 
     if (RuntimeEnvironment.getApiLevel() >= JELLY_BEAN_MR1) {
       map.put(Context.USER_SERVICE, createBinder(IUserManager.class, "android.os.IUserManager"));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
index b925f43..3de5456 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
@@ -6,6 +6,7 @@
 import static android.os.Build.VERSION_CODES.M;
 import static android.os.Build.VERSION_CODES.P;
 
+import android.app.ActivityThread;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.Build;
@@ -265,11 +266,21 @@
       return true;
     }
 
+    @Implementation(minSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    protected static boolean putString(String name, String value) {
+      return putString(ActivityThread.currentApplication().getContentResolver(), name, value);
+    }
+
     @Implementation
     protected static String getString(ContentResolver cr, String name) {
       return get(cr).get(name);
     }
 
+    @Implementation(minSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    protected static String getString(String name) {
+      return getString(ActivityThread.currentApplication().getContentResolver(), name);
+    }
+
     // BEGIN-INTERNAL
     @Implementation(minSdk = Build.VERSION_CODES.R)
     protected static Map<String, String> getStrings(ContentResolver cr, String prefix,
@@ -288,6 +299,12 @@
       }
       return arrayMap;
     }
+
+    @Implementation(minSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    protected static Map<String, String> getStrings(String prefix,
+            List<String> names) {
+      return getStrings(ActivityThread.currentApplication().getContentResolver(), prefix, names);
+    }
     // END-INTERNAL
 
     private static Map<String, String> get(ContentResolver cr) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java
index d5dd186..52a83e9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java
@@ -4,6 +4,7 @@
 import static android.os.Build.VERSION_CODES.N;
 import static android.os.Build.VERSION_CODES.N_MR1;
 import static android.os.Build.VERSION_CODES.P;
+import static android.os.Build.VERSION_CODES.TIRAMISU;
 import static org.robolectric.RuntimeEnvironment.application;
 import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
 import static org.robolectric.util.ReflectionHelpers.callConstructor;
@@ -261,6 +262,15 @@
           from(UsbManager.class, usbManager),
           from(String.class, id),
           from(int.class, supportedModes));
+    } else if (RuntimeEnvironment.getApiLevel() <= TIRAMISU) {
+      return new UsbPort(
+        usbManager,
+        id,
+        supportedModes,
+        0,
+        false,
+        false
+      );
     }
     // BEGIN-INTERNAL
     return new UsbPort(
@@ -269,7 +279,9 @@
         supportedModes,
         0,
         false,
-        false
+        false,
+        false,
+        0
     );
     // END-INTERNAL
   }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
index e1625d1..f4598aa 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
@@ -8,6 +8,7 @@
 import static android.os.Build.VERSION_CODES.N_MR1;
 import static android.os.Build.VERSION_CODES.R;
 import static android.os.Build.VERSION_CODES.TIRAMISU;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 
 import static org.robolectric.shadow.api.Shadow.directlyOn;
 
@@ -17,6 +18,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.content.pm.UserProperties;
 import android.os.Bundle;
 import android.os.IUserManager;
 import android.os.Process;
@@ -64,6 +66,10 @@
   private boolean userUnlocked = true;
   private boolean managedProfile = false;
   private boolean isSystemUser = true;
+  private static boolean isHeadlessSystemUserMode = false;
+  private static boolean isMultipleAdminEnabled = false;
+
+
   private Map<Integer, Bundle> userRestrictions = new HashMap<>();
   private BiMap<UserHandle, Long> userProfiles = HashBiMap.create();
   private Map<String, Bundle> applicationRestrictions = new HashMap<>();
@@ -72,6 +78,7 @@
   private Map<Integer, UserInfo> userInfoMap = new HashMap<>();
   private Map<Integer, List<UserInfo>> profiles = new HashMap<>();
   private Map<Integer, Integer> profileToParent = new HashMap<>();
+  private Map<Integer, UserProperties> mUserPropertiesMap = new HashMap<>();
 
   private Context context;
   private boolean enforcePermissions;
@@ -341,6 +348,24 @@
     return context.getPackageManager().checkPermission(permission.MANAGE_USERS, context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
   }
 
+  public static void setIsMultipleAdminEnabled(boolean enableMultipleAdmin) {
+    isMultipleAdminEnabled = enableMultipleAdmin;
+  }
+
+  @Implementation(minSdk = UPSIDE_DOWN_CAKE)
+  protected static boolean isMultipleAdminEnabled() {
+    return isMultipleAdminEnabled;
+  }
+
+  public static void setIsHeadlessSystemUserMode(boolean isHSUM) {
+    isHeadlessSystemUserMode = isHSUM;
+  }
+
+  @Implementation
+  protected static boolean isHeadlessSystemUserMode() {
+      return isHeadlessSystemUserMode;
+  }
+
   private void checkPermissions() {
     // TODO Ensure permisions
     //              throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS
@@ -636,5 +661,18 @@
       userPidMap.clear();
       userPidMap.put(UserHandle.USER_SYSTEM, Process.myUid());
     }
+    isMultipleAdminEnabled = false;
+  }
+
+  public void setupUserProperty(int userId, int showInSettings) {
+    UserProperties userProperties = new UserProperties(new UserProperties.Builder()
+            .setShowInSettings(showInSettings).build());
+    mUserPropertiesMap.putIfAbsent(userId, userProperties);
+  }
+
+  @Implementation(minSdk = UPSIDE_DOWN_CAKE)
+  protected UserProperties getUserProperties(UserHandle user) {
+    return mUserPropertiesMap.getOrDefault(user.getIdentifier(),
+            new UserProperties(new UserProperties.Builder().build()));
   }
 }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
index ad17119..5e6719c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
@@ -163,7 +163,7 @@
               ClassParameter.from(boolean.class, false),
               ClassParameter.from(int.class, 0));
       // END-INTERNAL
-    } else if (apiLevel >= Build.VERSION_CODES.TIRAMISU) {
+    } else if (apiLevel <= Build.VERSION_CODES.TIRAMISU) {
       // BEGIN-INTERNAL
       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
               ClassParameter.from(ClientWindowFrames.class, clientWindowFrame),
@@ -176,6 +176,19 @@
               ClassParameter.from(int.class, 0),
               ClassParameter.from(int.class, 0));
       // END-INTERNAL
+    } else if (apiLevel >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+      // BEGIN-INTERNAL
+      ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
+              ClassParameter.from(ClientWindowFrames.class, clientWindowFrame),
+              ClassParameter.from(boolean.class, true),
+              ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
+              ClassParameter.from(InsetsState.class, new InsetsState()),
+              ClassParameter.from(boolean.class, false),
+              ClassParameter.from(boolean.class, false),
+              ClassParameter.from(int.class, 0),
+              ClassParameter.from(int.class, 0),
+              ClassParameter.from(boolean.class, false));
+      // END-INTERNAL
     } else {
       throw new RuntimeException("Could not find AndroidRuntimeAdapter for API level: " + apiLevel);
     }
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
index a6aeaf2..a23dab9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
@@ -3,7 +3,10 @@
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
 
+import android.content.Context;
 import android.os.Looper;
+import android.os.ServiceManager;
+import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
@@ -32,7 +35,7 @@
 
   @Implementation
   public static Object getWindowManagerService() {
-    return null;
+    return IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
   }
 
 }
\ No newline at end of file
diff --git a/shadows/httpclient/Android.bp b/shadows/httpclient/Android.bp
index 39d57a8..d3ca43f 100644
--- a/shadows/httpclient/Android.bp
+++ b/shadows/httpclient/Android.bp
@@ -55,14 +55,14 @@
         "bouncycastle-unbundled",
         "hamcrest",
         "robolectric-httpclient-4.0.3",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "robolectric-httpcore-4.0.1",
         "guava",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "junit",
         "truth-prebuilt",
         "robolectric-ant-1.8.0",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
         "robolectric-host-android_all",
         "robolectric-host-org_apache_http_legacy",
diff --git a/shadows/supportv4/Android.bp b/shadows/supportv4/Android.bp
index 04714e5..c2fd480 100644
--- a/shadows/supportv4/Android.bp
+++ b/shadows/supportv4/Android.bp
@@ -53,14 +53,14 @@
         "mockito",
         "bouncycastle-unbundled",
         "hamcrest",
-        "asm-commons-9.2",
+        "ow2-asm-commons",
         "guava",
         "objenesis",
-        "asm-tree-9.2",
+        "ow2-asm-tree",
         "junit",
         "truth-prebuilt",
         "robolectric-ant-1.8.0",
-        "asm-9.2",
+        "ow2-asm",
         "jsr305",
     ],
     libs: ["robolectric-host-android_all"],