Merge "Add a config to control split-screen task dimming"
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 39f055b..a542c5c 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -134,11 +134,7 @@
     defaults: ["android-non-updatable-doc-stubs-defaults"],
     srcs: [":all-modules-public-stubs-source"],
     args: metalava_framework_docs_args,
-    api_levels_annotations_enabled: true,
-    api_levels_annotations_dirs: [
-        "sdk-dir",
-        "api-versions-jars-dir",
-    ],
+    api_levels_module: "api_versions_public",
     aidl: {
         include_dirs: [
             "packages/modules/Connectivity/framework/aidl-export",
diff --git a/INPUT_OWNERS b/INPUT_OWNERS
index 6041f637f..051216f 100644
--- a/INPUT_OWNERS
+++ b/INPUT_OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 136048
 michaelwr@google.com
 prabirmsp@google.com
 svv@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index c5c6012..3a6b347 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -17,6 +17,14 @@
   ],
   "presubmit": [
     {
+      "name": "ManagedProvisioningTests",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    },
+    {
       "name": "FrameworksUiServicesTests",
       "options": [
         {
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index e0c11cf..56fa70c 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -10,6 +10,7 @@
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.VIBRATE" />
 
     <application>
diff --git a/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java
new file mode 100644
index 0000000..e0c12dd
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+
+/**
+ * Tries to measure important BigInteger operations across a variety of BigInteger sizes. Note that
+ * BigInteger implementations commonly need to use wildly different algorithms for different sizes,
+ * so relative performance may change substantially depending on the size of the integer. This is
+ * not structured as a proper benchmark; just run main(), e.g. with vogar
+ * libcore/benchmarks/src/benchmarks/BigIntegerBenchmark.java.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class BigIntegerPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    // A simple sum of products computation, mostly so we can check timing in the
+    // absence of any division. Computes the sum from 1 to n of ((10^prec) << 30) + 1)^2,
+    // repeating the multiplication, but not addition of 1, each time through the loop.
+    // Check the last few bits of the result as we go. Assumes n < 2^30.
+    // Note that we're actually squaring values in computing the product.
+    // That affects the algorithm used by some implementations.
+    private static void inner(int n, int prec) {
+        BigInteger big = BigInteger.TEN.pow(prec).shiftLeft(30).add(BigInteger.ONE);
+        BigInteger sum = BigInteger.ZERO;
+        for (int i = 0; i < n; ++i) {
+            sum = sum.add(big.multiply(big));
+        }
+        if (sum.and(BigInteger.valueOf(0x3fffffff)).intValue() != n) {
+            throw new AssertionError(
+                    "inner() got " + sum.and(BigInteger.valueOf(0x3fffffff)) + " instead of " + n);
+        }
+    }
+
+    // Execute the above rep times, optionally timing it.
+    @Test
+    public void repeatInner() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 10; i <= 10_000; i *= 10) {
+                inner(100, i);
+            }
+        }
+    }
+
+    // Approximate the sum of the first 1000 terms of the harmonic series (sum of 1/m as m
+    // goes from 1 to n) to about prec digits. The result has an implicit decimal point
+    // prec digits from the right.
+    private static BigInteger harmonic1000(int prec) {
+        BigInteger scaledOne = BigInteger.TEN.pow(prec);
+        BigInteger sum = BigInteger.ZERO;
+        for (int i = 1; i <= 1000; ++i) {
+            sum = sum.add(scaledOne.divide(BigInteger.valueOf(i)));
+        }
+        return sum;
+    }
+
+    // Execute the above rep times, optionally timing it.
+    // Check results for equality, and print one, to compaare against reference.
+    @Test
+    public void repeatHarmonic1000() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 5; i <= 5_000; i *= 10) {
+                BigInteger refRes = harmonic1000(i);
+                BigInteger newRes = harmonic1000(i);
+                if (!newRes.equals(refRes)) {
+                    throw new AssertionError(newRes + " != " + refRes);
+                }
+                if (i >= 50
+                        && !refRes.toString()
+                                .startsWith("748547086055034491265651820433390017652167916970")) {
+                    throw new AssertionError("harmanic(" + i + ") incorrectly produced " + refRes);
+                }
+            }
+        }
+    }
+
+    // Repeatedly execute just the base conversion from the last test, allowing
+    // us to time and check it for consistency as well.
+    @Test
+    public void repeatToString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 5; i <= 5_000; i *= 10) {
+                BigInteger refRes = harmonic1000(i);
+                String refString = refRes.toString();
+                // Disguise refRes to avoid compiler optimization issues.
+                BigInteger newRes = refRes.shiftLeft(30).add(BigInteger.valueOf(i)).shiftRight(30);
+                // The time-consuming part:
+                String newString = newRes.toString();
+            }
+        }
+    }
+
+    // Compute base^exp, where base and result are scaled/multiplied by scaleBy to make them
+    // integers. exp >= 0 .
+    private static BigInteger myPow(BigInteger base, int exp, BigInteger scaleBy) {
+        if (exp == 0) {
+            return scaleBy; // Return one.
+        } else if ((exp & 1) != 0) {
+            BigInteger tmp = myPow(base, exp - 1, scaleBy);
+            return tmp.multiply(base).divide(scaleBy);
+        } else {
+            BigInteger tmp = myPow(base, exp / 2, scaleBy);
+            return tmp.multiply(tmp).divide(scaleBy);
+        }
+    }
+
+    // Approximate e by computing (1 + 1/n)^n to prec decimal digits.
+    // This isn't necessarily a very good approximation to e.
+    // Return the result, scaled by 10^prec.
+    private static BigInteger eApprox(int n, int prec) {
+        BigInteger scaledOne = BigInteger.TEN.pow(prec);
+        BigInteger base = scaledOne.add(scaledOne.divide(BigInteger.valueOf(n)));
+        return myPow(base, n, scaledOne);
+    }
+
+    // Repeatedly execute and check the above, printing one of the results
+    // to compare to reference.
+    @Test
+    public void repeatEApprox() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 10; i <= 10_000; i *= 10) {
+                BigInteger refRes = eApprox(100_000, i);
+                BigInteger newRes = eApprox(100_000, i);
+                if (!newRes.equals(refRes)) {
+                    throw new AssertionError(newRes + " != " + refRes);
+                }
+                if (i >= 10 && !refRes.toString().startsWith("271826")) {
+                    throw new AssertionError(
+                            "eApprox(" + 100_000 + "," + i + ") incorrectly produced " + refRes);
+                }
+            }
+        }
+    }
+
+    // Test / time modPow()
+    @Test
+    public void repeatModPow() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 5; i <= 500; i *= 10) {
+                BigInteger odd1 = BigInteger.TEN.pow(i / 2).add(BigInteger.ONE);
+                BigInteger odd2 = BigInteger.TEN.pow(i / 2).add(BigInteger.valueOf(17));
+                BigInteger product = odd1.multiply(odd2);
+                BigInteger exponent = BigInteger.TEN.pow(i / 2 - 1);
+                BigInteger base = BigInteger.TEN.pow(i / 4);
+                BigInteger newRes = base.modPow(exponent, product);
+                if (!newRes.mod(odd1).equals(base.modPow(exponent, odd1))) {
+                    throw new AssertionError(
+                            "ModPow() result incorrect mod odd1:"
+                                    + odd1
+                                    + "; lastRes.mod(odd1)="
+                                    + newRes.mod(odd1)
+                                    + " vs. "
+                                    + "base.modPow(exponent, odd1)="
+                                    + base.modPow(exponent, odd1)
+                                    + " base="
+                                    + base
+                                    + " exponent="
+                                    + exponent);
+                }
+                if (!newRes.mod(odd2).equals(base.modPow(exponent, odd2))) {
+                    throw new AssertionError("ModPow() result incorrect mod odd2");
+                }
+            }
+        }
+    }
+
+    // Test / time modInverse()
+    @Test
+    public void repeatModInverse() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 10; i <= 10_000; i *= 10) {
+                BigInteger odd1 = BigInteger.TEN.pow(i / 2).add(BigInteger.ONE);
+                BigInteger odd2 = BigInteger.TEN.pow(i / 2).add(BigInteger.valueOf(17));
+                BigInteger product = odd1.multiply(odd2);
+                BigInteger arg = BigInteger.ONE.shiftLeft(i / 4);
+                BigInteger lastRes = null;
+                BigInteger newRes = arg.modInverse(product);
+                lastRes = newRes;
+                if (!lastRes.mod(odd1).equals(arg.modInverse(odd1))) {
+                    throw new AssertionError("ModInverse() result incorrect mod odd1");
+                }
+                if (!lastRes.mod(odd2).equals(arg.modInverse(odd2))) {
+                    throw new AssertionError("ModInverse() result incorrect mod odd2");
+                }
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java
new file mode 100644
index 0000000..04ef09e4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Random;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public final class BufferedZipFilePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    int[] mReadSize = new int[] {4, 32, 128};
+    int[] mCompressedSize = new int[] {128, 1024, 8192, 65536};
+    private File mFile;
+
+    @Before
+    public void setUp() throws Exception {
+        mFile = File.createTempFile("BufferedZipFilePerfTest", ".zip");
+        mFile.deleteOnExit();
+        Random random = new Random(0);
+        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(mFile));
+        for (int i = 0; i < mCompressedSize.length; i++) {
+            byte[] data = new byte[8192];
+            out.putNextEntry(new ZipEntry("entry.data" + mCompressedSize[i]));
+            int written = 0;
+            while (written < mCompressedSize[i]) {
+                random.nextBytes(data);
+                int toWrite = Math.min(mCompressedSize[i] - written, data.length);
+                out.write(data, 0, toWrite);
+                written += toWrite;
+            }
+        }
+        out.close();
+    }
+
+    @Test
+    public void timeUnbufferedRead() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mCompressedSize.length; i++) {
+                for (int j = 0; j < mReadSize.length; j++) {
+                    ZipFile zipFile = new ZipFile(mFile);
+                    ZipEntry entry = zipFile.getEntry("entry.data" + mCompressedSize[i]);
+                    InputStream in = zipFile.getInputStream(entry);
+                    byte[] buffer = new byte[mReadSize[j]];
+                    while (in.read(buffer) != -1) {
+                        // Keep reading
+                    }
+                    in.close();
+                    zipFile.close();
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeBufferedRead() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < mCompressedSize.length; i++) {
+                for (int j = 0; j < mReadSize.length; j++) {
+                    ZipFile zipFile = new ZipFile(mFile);
+                    ZipEntry entry = zipFile.getEntry("entry.data" + mCompressedSize[i]);
+                    InputStream in = new BufferedInputStream(zipFile.getInputStream(entry));
+                    byte[] buffer = new byte[mReadSize[j]];
+                    while (in.read(buffer) != -1) {
+                        // Keep reading
+                    }
+                    in.close();
+                    zipFile.close();
+                }
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java
new file mode 100644
index 0000000..4ae88b8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ClassLoaderResourcePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final String EXISTENT_RESOURCE = "java/util/logging/logging.properties";
+    private static final String MISSING_RESOURCE = "missing_entry";
+
+    @Test
+    public void timeGetBootResource_hit() {
+        ClassLoader currentClassLoader = getClass().getClassLoader();
+        Assert.assertNotNull(currentClassLoader.getResource(EXISTENT_RESOURCE));
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            currentClassLoader.getResource(EXISTENT_RESOURCE);
+        }
+    }
+
+    @Test
+    public void timeGetBootResource_miss() {
+        ClassLoader currentClassLoader = getClass().getClassLoader();
+        Assert.assertNull(currentClassLoader.getResource(MISSING_RESOURCE));
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            currentClassLoader.getResource(MISSING_RESOURCE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
new file mode 100644
index 0000000..5e73916
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
@@ -0,0 +1,1197 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ClonePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    static class CloneableObject implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+    }
+
+    static class CloneableManyFieldObject implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+
+        Object mO1 = new Object();
+        Object mO2 = new Object();
+        Object mO3 = new Object();
+        Object mO4 = new Object();
+        Object mO5 = new Object();
+        Object mO6 = new Object();
+        Object mO7 = new Object();
+        Object mO8 = new Object();
+        Object mO9 = new Object();
+        Object mO10 = new Object();
+        Object mO11 = new Object();
+        Object mO12 = new Object();
+        Object mO13 = new Object();
+        Object mO14 = new Object();
+        Object mO15 = new Object();
+        Object mO16 = new Object();
+        Object mO17 = new Object();
+        Object mO18 = new Object();
+        Object mO19 = new Object();
+        Object mO20 = new Object();
+        Object mO21 = new Object();
+        Object mO22 = new Object();
+        Object mO23 = new Object();
+        Object mO24 = new Object();
+        Object mO25 = new Object();
+        Object mO26 = new Object();
+        Object mO27 = new Object();
+        Object mO28 = new Object();
+        Object mO29 = new Object();
+        Object mO30 = new Object();
+        Object mO31 = new Object();
+        Object mO32 = new Object();
+        Object mO33 = new Object();
+        Object mO34 = new Object();
+        Object mO35 = new Object();
+        Object mO36 = new Object();
+        Object mO37 = new Object();
+        Object mO38 = new Object();
+        Object mO39 = new Object();
+        Object mO40 = new Object();
+        Object mO41 = new Object();
+        Object mO42 = new Object();
+        Object mO43 = new Object();
+        Object mO44 = new Object();
+        Object mO45 = new Object();
+        Object mO46 = new Object();
+        Object mO47 = new Object();
+        Object mO48 = new Object();
+        Object mO49 = new Object();
+        Object mO50 = new Object();
+        Object mO51 = new Object();
+        Object mO52 = new Object();
+        Object mO53 = new Object();
+        Object mO54 = new Object();
+        Object mO55 = new Object();
+        Object mO56 = new Object();
+        Object mO57 = new Object();
+        Object mO58 = new Object();
+        Object mO59 = new Object();
+        Object mO60 = new Object();
+        Object mO61 = new Object();
+        Object mO62 = new Object();
+        Object mO63 = new Object();
+        Object mO64 = new Object();
+        Object mO65 = new Object();
+        Object mO66 = new Object();
+        Object mO67 = new Object();
+        Object mO68 = new Object();
+        Object mO69 = new Object();
+        Object mO70 = new Object();
+        Object mO71 = new Object();
+        Object mO72 = new Object();
+        Object mO73 = new Object();
+        Object mO74 = new Object();
+        Object mO75 = new Object();
+        Object mO76 = new Object();
+        Object mO77 = new Object();
+        Object mO78 = new Object();
+        Object mO79 = new Object();
+        Object mO80 = new Object();
+        Object mO81 = new Object();
+        Object mO82 = new Object();
+        Object mO83 = new Object();
+        Object mO84 = new Object();
+        Object mO85 = new Object();
+        Object mO86 = new Object();
+        Object mO87 = new Object();
+        Object mO88 = new Object();
+        Object mO89 = new Object();
+        Object mO90 = new Object();
+        Object mO91 = new Object();
+        Object mO92 = new Object();
+        Object mO93 = new Object();
+        Object mO94 = new Object();
+        Object mO95 = new Object();
+        Object mO96 = new Object();
+        Object mO97 = new Object();
+        Object mO98 = new Object();
+        Object mO99 = new Object();
+        Object mO100 = new Object();
+        Object mO101 = new Object();
+        Object mO102 = new Object();
+        Object mO103 = new Object();
+        Object mO104 = new Object();
+        Object mO105 = new Object();
+        Object mO106 = new Object();
+        Object mO107 = new Object();
+        Object mO108 = new Object();
+        Object mO109 = new Object();
+        Object mO110 = new Object();
+        Object mO111 = new Object();
+        Object mO112 = new Object();
+        Object mO113 = new Object();
+        Object mO114 = new Object();
+        Object mO115 = new Object();
+        Object mO116 = new Object();
+        Object mO117 = new Object();
+        Object mO118 = new Object();
+        Object mO119 = new Object();
+        Object mO120 = new Object();
+        Object mO121 = new Object();
+        Object mO122 = new Object();
+        Object mO123 = new Object();
+        Object mO124 = new Object();
+        Object mO125 = new Object();
+        Object mO126 = new Object();
+        Object mO127 = new Object();
+        Object mO128 = new Object();
+        Object mO129 = new Object();
+        Object mO130 = new Object();
+        Object mO131 = new Object();
+        Object mO132 = new Object();
+        Object mO133 = new Object();
+        Object mO134 = new Object();
+        Object mO135 = new Object();
+        Object mO136 = new Object();
+        Object mO137 = new Object();
+        Object mO138 = new Object();
+        Object mO139 = new Object();
+        Object mO140 = new Object();
+        Object mO141 = new Object();
+        Object mO142 = new Object();
+        Object mO143 = new Object();
+        Object mO144 = new Object();
+        Object mO145 = new Object();
+        Object mO146 = new Object();
+        Object mO147 = new Object();
+        Object mO148 = new Object();
+        Object mO149 = new Object();
+        Object mO150 = new Object();
+        Object mO151 = new Object();
+        Object mO152 = new Object();
+        Object mO153 = new Object();
+        Object mO154 = new Object();
+        Object mO155 = new Object();
+        Object mO156 = new Object();
+        Object mO157 = new Object();
+        Object mO158 = new Object();
+        Object mO159 = new Object();
+        Object mO160 = new Object();
+        Object mO161 = new Object();
+        Object mO162 = new Object();
+        Object mO163 = new Object();
+        Object mO164 = new Object();
+        Object mO165 = new Object();
+        Object mO166 = new Object();
+        Object mO167 = new Object();
+        Object mO168 = new Object();
+        Object mO169 = new Object();
+        Object mO170 = new Object();
+        Object mO171 = new Object();
+        Object mO172 = new Object();
+        Object mO173 = new Object();
+        Object mO174 = new Object();
+        Object mO175 = new Object();
+        Object mO176 = new Object();
+        Object mO177 = new Object();
+        Object mO178 = new Object();
+        Object mO179 = new Object();
+        Object mO180 = new Object();
+        Object mO181 = new Object();
+        Object mO182 = new Object();
+        Object mO183 = new Object();
+        Object mO184 = new Object();
+        Object mO185 = new Object();
+        Object mO186 = new Object();
+        Object mO187 = new Object();
+        Object mO188 = new Object();
+        Object mO189 = new Object();
+        Object mO190 = new Object();
+        Object mO191 = new Object();
+        Object mO192 = new Object();
+        Object mO193 = new Object();
+        Object mO194 = new Object();
+        Object mO195 = new Object();
+        Object mO196 = new Object();
+        Object mO197 = new Object();
+        Object mO198 = new Object();
+        Object mO199 = new Object();
+        Object mO200 = new Object();
+        Object mO201 = new Object();
+        Object mO202 = new Object();
+        Object mO203 = new Object();
+        Object mO204 = new Object();
+        Object mO205 = new Object();
+        Object mO206 = new Object();
+        Object mO207 = new Object();
+        Object mO208 = new Object();
+        Object mO209 = new Object();
+        Object mO210 = new Object();
+        Object mO211 = new Object();
+        Object mO212 = new Object();
+        Object mO213 = new Object();
+        Object mO214 = new Object();
+        Object mO215 = new Object();
+        Object mO216 = new Object();
+        Object mO217 = new Object();
+        Object mO218 = new Object();
+        Object mO219 = new Object();
+        Object mO220 = new Object();
+        Object mO221 = new Object();
+        Object mO222 = new Object();
+        Object mO223 = new Object();
+        Object mO224 = new Object();
+        Object mO225 = new Object();
+        Object mO226 = new Object();
+        Object mO227 = new Object();
+        Object mO228 = new Object();
+        Object mO229 = new Object();
+        Object mO230 = new Object();
+        Object mO231 = new Object();
+        Object mO232 = new Object();
+        Object mO233 = new Object();
+        Object mO234 = new Object();
+        Object mO235 = new Object();
+        Object mO236 = new Object();
+        Object mO237 = new Object();
+        Object mO238 = new Object();
+        Object mO239 = new Object();
+        Object mO240 = new Object();
+        Object mO241 = new Object();
+        Object mO242 = new Object();
+        Object mO243 = new Object();
+        Object mO244 = new Object();
+        Object mO245 = new Object();
+        Object mO246 = new Object();
+        Object mO247 = new Object();
+        Object mO248 = new Object();
+        Object mO249 = new Object();
+        Object mO250 = new Object();
+        Object mO251 = new Object();
+        Object mO252 = new Object();
+        Object mO253 = new Object();
+        Object mO254 = new Object();
+        Object mO255 = new Object();
+        Object mO256 = new Object();
+        Object mO257 = new Object();
+        Object mO258 = new Object();
+        Object mO259 = new Object();
+        Object mO260 = new Object();
+        Object mO261 = new Object();
+        Object mO262 = new Object();
+        Object mO263 = new Object();
+        Object mO264 = new Object();
+        Object mO265 = new Object();
+        Object mO266 = new Object();
+        Object mO267 = new Object();
+        Object mO268 = new Object();
+        Object mO269 = new Object();
+        Object mO270 = new Object();
+        Object mO271 = new Object();
+        Object mO272 = new Object();
+        Object mO273 = new Object();
+        Object mO274 = new Object();
+        Object mO275 = new Object();
+        Object mO276 = new Object();
+        Object mO277 = new Object();
+        Object mO278 = new Object();
+        Object mO279 = new Object();
+        Object mO280 = new Object();
+        Object mO281 = new Object();
+        Object mO282 = new Object();
+        Object mO283 = new Object();
+        Object mO284 = new Object();
+        Object mO285 = new Object();
+        Object mO286 = new Object();
+        Object mO287 = new Object();
+        Object mO288 = new Object();
+        Object mO289 = new Object();
+        Object mO290 = new Object();
+        Object mO291 = new Object();
+        Object mO292 = new Object();
+        Object mO293 = new Object();
+        Object mO294 = new Object();
+        Object mO295 = new Object();
+        Object mO296 = new Object();
+        Object mO297 = new Object();
+        Object mO298 = new Object();
+        Object mO299 = new Object();
+        Object mO300 = new Object();
+        Object mO301 = new Object();
+        Object mO302 = new Object();
+        Object mO303 = new Object();
+        Object mO304 = new Object();
+        Object mO305 = new Object();
+        Object mO306 = new Object();
+        Object mO307 = new Object();
+        Object mO308 = new Object();
+        Object mO309 = new Object();
+        Object mO310 = new Object();
+        Object mO311 = new Object();
+        Object mO312 = new Object();
+        Object mO313 = new Object();
+        Object mO314 = new Object();
+        Object mO315 = new Object();
+        Object mO316 = new Object();
+        Object mO317 = new Object();
+        Object mO318 = new Object();
+        Object mO319 = new Object();
+        Object mO320 = new Object();
+        Object mO321 = new Object();
+        Object mO322 = new Object();
+        Object mO323 = new Object();
+        Object mO324 = new Object();
+        Object mO325 = new Object();
+        Object mO326 = new Object();
+        Object mO327 = new Object();
+        Object mO328 = new Object();
+        Object mO329 = new Object();
+        Object mO330 = new Object();
+        Object mO331 = new Object();
+        Object mO332 = new Object();
+        Object mO333 = new Object();
+        Object mO334 = new Object();
+        Object mO335 = new Object();
+        Object mO336 = new Object();
+        Object mO337 = new Object();
+        Object mO338 = new Object();
+        Object mO339 = new Object();
+        Object mO340 = new Object();
+        Object mO341 = new Object();
+        Object mO342 = new Object();
+        Object mO343 = new Object();
+        Object mO344 = new Object();
+        Object mO345 = new Object();
+        Object mO346 = new Object();
+        Object mO347 = new Object();
+        Object mO348 = new Object();
+        Object mO349 = new Object();
+        Object mO350 = new Object();
+        Object mO351 = new Object();
+        Object mO352 = new Object();
+        Object mO353 = new Object();
+        Object mO354 = new Object();
+        Object mO355 = new Object();
+        Object mO356 = new Object();
+        Object mO357 = new Object();
+        Object mO358 = new Object();
+        Object mO359 = new Object();
+        Object mO360 = new Object();
+        Object mO361 = new Object();
+        Object mO362 = new Object();
+        Object mO363 = new Object();
+        Object mO364 = new Object();
+        Object mO365 = new Object();
+        Object mO366 = new Object();
+        Object mO367 = new Object();
+        Object mO368 = new Object();
+        Object mO369 = new Object();
+        Object mO370 = new Object();
+        Object mO371 = new Object();
+        Object mO372 = new Object();
+        Object mO373 = new Object();
+        Object mO374 = new Object();
+        Object mO375 = new Object();
+        Object mO376 = new Object();
+        Object mO377 = new Object();
+        Object mO378 = new Object();
+        Object mO379 = new Object();
+        Object mO380 = new Object();
+        Object mO381 = new Object();
+        Object mO382 = new Object();
+        Object mO383 = new Object();
+        Object mO384 = new Object();
+        Object mO385 = new Object();
+        Object mO386 = new Object();
+        Object mO387 = new Object();
+        Object mO388 = new Object();
+        Object mO389 = new Object();
+        Object mO390 = new Object();
+        Object mO391 = new Object();
+        Object mO392 = new Object();
+        Object mO393 = new Object();
+        Object mO394 = new Object();
+        Object mO395 = new Object();
+        Object mO396 = new Object();
+        Object mO397 = new Object();
+        Object mO398 = new Object();
+        Object mO399 = new Object();
+        Object mO400 = new Object();
+        Object mO401 = new Object();
+        Object mO402 = new Object();
+        Object mO403 = new Object();
+        Object mO404 = new Object();
+        Object mO405 = new Object();
+        Object mO406 = new Object();
+        Object mO407 = new Object();
+        Object mO408 = new Object();
+        Object mO409 = new Object();
+        Object mO410 = new Object();
+        Object mO411 = new Object();
+        Object mO412 = new Object();
+        Object mO413 = new Object();
+        Object mO414 = new Object();
+        Object mO415 = new Object();
+        Object mO416 = new Object();
+        Object mO417 = new Object();
+        Object mO418 = new Object();
+        Object mO419 = new Object();
+        Object mO420 = new Object();
+        Object mO421 = new Object();
+        Object mO422 = new Object();
+        Object mO423 = new Object();
+        Object mO424 = new Object();
+        Object mO425 = new Object();
+        Object mO426 = new Object();
+        Object mO427 = new Object();
+        Object mO428 = new Object();
+        Object mO429 = new Object();
+        Object mO430 = new Object();
+        Object mO431 = new Object();
+        Object mO432 = new Object();
+        Object mO433 = new Object();
+        Object mO434 = new Object();
+        Object mO435 = new Object();
+        Object mO436 = new Object();
+        Object mO437 = new Object();
+        Object mO438 = new Object();
+        Object mO439 = new Object();
+        Object mO440 = new Object();
+        Object mO441 = new Object();
+        Object mO442 = new Object();
+        Object mO460 = new Object();
+        Object mO461 = new Object();
+        Object mO462 = new Object();
+        Object mO463 = new Object();
+        Object mO464 = new Object();
+        Object mO465 = new Object();
+        Object mO466 = new Object();
+        Object mO467 = new Object();
+        Object mO468 = new Object();
+        Object mO469 = new Object();
+        Object mO470 = new Object();
+        Object mO471 = new Object();
+        Object mO472 = new Object();
+        Object mO473 = new Object();
+        Object mO474 = new Object();
+        Object mO475 = new Object();
+        Object mO476 = new Object();
+        Object mO477 = new Object();
+        Object mO478 = new Object();
+        Object mO479 = new Object();
+        Object mO480 = new Object();
+        Object mO481 = new Object();
+        Object mO482 = new Object();
+        Object mO483 = new Object();
+        Object mO484 = new Object();
+        Object mO485 = new Object();
+        Object mO486 = new Object();
+        Object mO487 = new Object();
+        Object mO488 = new Object();
+        Object mO489 = new Object();
+        Object mO490 = new Object();
+        Object mO491 = new Object();
+        Object mO492 = new Object();
+        Object mO493 = new Object();
+        Object mO494 = new Object();
+        Object mO495 = new Object();
+        Object mO496 = new Object();
+        Object mO497 = new Object();
+        Object mO498 = new Object();
+        Object mO499 = new Object();
+        Object mO500 = new Object();
+        Object mO501 = new Object();
+        Object mO502 = new Object();
+        Object mO503 = new Object();
+        Object mO504 = new Object();
+        Object mO505 = new Object();
+        Object mO506 = new Object();
+        Object mO507 = new Object();
+        Object mO508 = new Object();
+        Object mO509 = new Object();
+        Object mO510 = new Object();
+        Object mO511 = new Object();
+        Object mO512 = new Object();
+        Object mO513 = new Object();
+        Object mO514 = new Object();
+        Object mO515 = new Object();
+        Object mO516 = new Object();
+        Object mO517 = new Object();
+        Object mO518 = new Object();
+        Object mO519 = new Object();
+        Object mO520 = new Object();
+        Object mO521 = new Object();
+        Object mO522 = new Object();
+        Object mO523 = new Object();
+        Object mO556 = new Object();
+        Object mO557 = new Object();
+        Object mO558 = new Object();
+        Object mO559 = new Object();
+        Object mO560 = new Object();
+        Object mO561 = new Object();
+        Object mO562 = new Object();
+        Object mO563 = new Object();
+        Object mO564 = new Object();
+        Object mO565 = new Object();
+        Object mO566 = new Object();
+        Object mO567 = new Object();
+        Object mO568 = new Object();
+        Object mO569 = new Object();
+        Object mO570 = new Object();
+        Object mO571 = new Object();
+        Object mO572 = new Object();
+        Object mO573 = new Object();
+        Object mO574 = new Object();
+        Object mO575 = new Object();
+        Object mO576 = new Object();
+        Object mO577 = new Object();
+        Object mO578 = new Object();
+        Object mO579 = new Object();
+        Object mO580 = new Object();
+        Object mO581 = new Object();
+        Object mO582 = new Object();
+        Object mO583 = new Object();
+        Object mO584 = new Object();
+        Object mO585 = new Object();
+        Object mO586 = new Object();
+        Object mO587 = new Object();
+        Object mO588 = new Object();
+        Object mO589 = new Object();
+        Object mO590 = new Object();
+        Object mO591 = new Object();
+        Object mO592 = new Object();
+        Object mO593 = new Object();
+        Object mO594 = new Object();
+        Object mO595 = new Object();
+        Object mO596 = new Object();
+        Object mO597 = new Object();
+        Object mO598 = new Object();
+        Object mO599 = new Object();
+        Object mO600 = new Object();
+        Object mO601 = new Object();
+        Object mO602 = new Object();
+        Object mO603 = new Object();
+        Object mO604 = new Object();
+        Object mO605 = new Object();
+        Object mO606 = new Object();
+        Object mO607 = new Object();
+        Object mO608 = new Object();
+        Object mO609 = new Object();
+        Object mO610 = new Object();
+        Object mO611 = new Object();
+        Object mO612 = new Object();
+        Object mO613 = new Object();
+        Object mO614 = new Object();
+        Object mO615 = new Object();
+        Object mO616 = new Object();
+        Object mO617 = new Object();
+        Object mO618 = new Object();
+        Object mO619 = new Object();
+        Object mO620 = new Object();
+        Object mO621 = new Object();
+        Object mO622 = new Object();
+        Object mO623 = new Object();
+        Object mO624 = new Object();
+        Object mO625 = new Object();
+        Object mO626 = new Object();
+        Object mO627 = new Object();
+        Object mO628 = new Object();
+        Object mO629 = new Object();
+        Object mO630 = new Object();
+        Object mO631 = new Object();
+        Object mO632 = new Object();
+        Object mO633 = new Object();
+        Object mO634 = new Object();
+        Object mO635 = new Object();
+        Object mO636 = new Object();
+        Object mO637 = new Object();
+        Object mO638 = new Object();
+        Object mO639 = new Object();
+        Object mO640 = new Object();
+        Object mO641 = new Object();
+        Object mO642 = new Object();
+        Object mO643 = new Object();
+        Object mO644 = new Object();
+        Object mO645 = new Object();
+        Object mO646 = new Object();
+        Object mO647 = new Object();
+        Object mO648 = new Object();
+        Object mO649 = new Object();
+        Object mO650 = new Object();
+        Object mO651 = new Object();
+        Object mO652 = new Object();
+        Object mO653 = new Object();
+        Object mO654 = new Object();
+        Object mO655 = new Object();
+        Object mO656 = new Object();
+        Object mO657 = new Object();
+        Object mO658 = new Object();
+        Object mO659 = new Object();
+        Object mO660 = new Object();
+        Object mO661 = new Object();
+        Object mO662 = new Object();
+        Object mO663 = new Object();
+        Object mO664 = new Object();
+        Object mO665 = new Object();
+        Object mO666 = new Object();
+        Object mO667 = new Object();
+        Object mO668 = new Object();
+        Object mO669 = new Object();
+        Object mO670 = new Object();
+        Object mO671 = new Object();
+        Object mO672 = new Object();
+        Object mO673 = new Object();
+        Object mO674 = new Object();
+        Object mO675 = new Object();
+        Object mO676 = new Object();
+        Object mO677 = new Object();
+        Object mO678 = new Object();
+        Object mO679 = new Object();
+        Object mO680 = new Object();
+        Object mO681 = new Object();
+        Object mO682 = new Object();
+        Object mO683 = new Object();
+        Object mO684 = new Object();
+        Object mO685 = new Object();
+        Object mO686 = new Object();
+        Object mO687 = new Object();
+        Object mO688 = new Object();
+        Object mO734 = new Object();
+        Object mO735 = new Object();
+        Object mO736 = new Object();
+        Object mO737 = new Object();
+        Object mO738 = new Object();
+        Object mO739 = new Object();
+        Object mO740 = new Object();
+        Object mO741 = new Object();
+        Object mO742 = new Object();
+        Object mO743 = new Object();
+        Object mO744 = new Object();
+        Object mO745 = new Object();
+        Object mO746 = new Object();
+        Object mO747 = new Object();
+        Object mO748 = new Object();
+        Object mO749 = new Object();
+        Object mO750 = new Object();
+        Object mO751 = new Object();
+        Object mO752 = new Object();
+        Object mO753 = new Object();
+        Object mO754 = new Object();
+        Object mO755 = new Object();
+        Object mO756 = new Object();
+        Object mO757 = new Object();
+        Object mO758 = new Object();
+        Object mO759 = new Object();
+        Object mO760 = new Object();
+        Object mO761 = new Object();
+        Object mO762 = new Object();
+        Object mO763 = new Object();
+        Object mO764 = new Object();
+        Object mO765 = new Object();
+        Object mO766 = new Object();
+        Object mO767 = new Object();
+        Object mO768 = new Object();
+        Object mO769 = new Object();
+        Object mO770 = new Object();
+        Object mO771 = new Object();
+        Object mO772 = new Object();
+        Object mO773 = new Object();
+        Object mO774 = new Object();
+        Object mO775 = new Object();
+        Object mO776 = new Object();
+        Object mO777 = new Object();
+        Object mO778 = new Object();
+        Object mO779 = new Object();
+        Object mO780 = new Object();
+        Object mO781 = new Object();
+        Object mO782 = new Object();
+        Object mO783 = new Object();
+        Object mO784 = new Object();
+        Object mO785 = new Object();
+        Object mO786 = new Object();
+        Object mO787 = new Object();
+        Object mO788 = new Object();
+        Object mO789 = new Object();
+        Object mO790 = new Object();
+        Object mO791 = new Object();
+        Object mO792 = new Object();
+        Object mO793 = new Object();
+        Object mO794 = new Object();
+        Object mO795 = new Object();
+        Object mO796 = new Object();
+        Object mO797 = new Object();
+        Object mO798 = new Object();
+        Object mO799 = new Object();
+        Object mO800 = new Object();
+        Object mO801 = new Object();
+        Object mO802 = new Object();
+        Object mO803 = new Object();
+        Object mO804 = new Object();
+        Object mO805 = new Object();
+        Object mO806 = new Object();
+        Object mO807 = new Object();
+        Object mO808 = new Object();
+        Object mO809 = new Object();
+        Object mO810 = new Object();
+        Object mO811 = new Object();
+        Object mO812 = new Object();
+        Object mO813 = new Object();
+        Object mO848 = new Object();
+        Object mO849 = new Object();
+        Object mO850 = new Object();
+        Object mO851 = new Object();
+        Object mO852 = new Object();
+        Object mO853 = new Object();
+        Object mO854 = new Object();
+        Object mO855 = new Object();
+        Object mO856 = new Object();
+        Object mO857 = new Object();
+        Object mO858 = new Object();
+        Object mO859 = new Object();
+        Object mO860 = new Object();
+        Object mO861 = new Object();
+        Object mO862 = new Object();
+        Object mO863 = new Object();
+        Object mO864 = new Object();
+        Object mO865 = new Object();
+        Object mO866 = new Object();
+        Object mO867 = new Object();
+        Object mO868 = new Object();
+        Object mO869 = new Object();
+        Object mO870 = new Object();
+        Object mO871 = new Object();
+        Object mO872 = new Object();
+        Object mO873 = new Object();
+        Object mO874 = new Object();
+        Object mO875 = new Object();
+        Object mO876 = new Object();
+        Object mO877 = new Object();
+        Object mO878 = new Object();
+        Object mO879 = new Object();
+        Object mO880 = new Object();
+        Object mO881 = new Object();
+        Object mO882 = new Object();
+        Object mO883 = new Object();
+        Object mO884 = new Object();
+        Object mO885 = new Object();
+        Object mO886 = new Object();
+        Object mO887 = new Object();
+        Object mO888 = new Object();
+        Object mO889 = new Object();
+        Object mO890 = new Object();
+        Object mO891 = new Object();
+        Object mO892 = new Object();
+        Object mO893 = new Object();
+        Object mO894 = new Object();
+        Object mO895 = new Object();
+        Object mO896 = new Object();
+        Object mO897 = new Object();
+        Object mO898 = new Object();
+        Object mO899 = new Object();
+        Object mO900 = new Object();
+        Object mO901 = new Object();
+        Object mO902 = new Object();
+        Object mO903 = new Object();
+        Object mO904 = new Object();
+        Object mO905 = new Object();
+        Object mO906 = new Object();
+        Object mO907 = new Object();
+        Object mO908 = new Object();
+        Object mO909 = new Object();
+        Object mO910 = new Object();
+        Object mO911 = new Object();
+        Object mO912 = new Object();
+        Object mO913 = new Object();
+        Object mO914 = new Object();
+        Object mO915 = new Object();
+        Object mO916 = new Object();
+        Object mO917 = new Object();
+        Object mO918 = new Object();
+        Object mO919 = new Object();
+        Object mO920 = new Object();
+        Object mO921 = new Object();
+        Object mO922 = new Object();
+        Object mO923 = new Object();
+        Object mO924 = new Object();
+        Object mO925 = new Object();
+        Object mO926 = new Object();
+        Object mO927 = new Object();
+        Object mO928 = new Object();
+        Object mO929 = new Object();
+        Object mO930 = new Object();
+        Object mO931 = new Object();
+        Object mO932 = new Object();
+        Object mO933 = new Object();
+        Object mO934 = new Object();
+        Object mO935 = new Object();
+        Object mO936 = new Object();
+        Object mO937 = new Object();
+        Object mO938 = new Object();
+        Object mO939 = new Object();
+        Object mO940 = new Object();
+        Object mO941 = new Object();
+        Object mO942 = new Object();
+        Object mO943 = new Object();
+        Object mO944 = new Object();
+        Object mO945 = new Object();
+        Object mO946 = new Object();
+        Object mO947 = new Object();
+        Object mO948 = new Object();
+        Object mO949 = new Object();
+        Object mO950 = new Object();
+        Object mO951 = new Object();
+        Object mO952 = new Object();
+        Object mO953 = new Object();
+        Object mO954 = new Object();
+        Object mO955 = new Object();
+        Object mO956 = new Object();
+        Object mO957 = new Object();
+        Object mO958 = new Object();
+        Object mO959 = new Object();
+        Object mO960 = new Object();
+        Object mO961 = new Object();
+        Object mO962 = new Object();
+        Object mO963 = new Object();
+        Object mO964 = new Object();
+        Object mO965 = new Object();
+        Object mO966 = new Object();
+        Object mO967 = new Object();
+        Object mO968 = new Object();
+        Object mO969 = new Object();
+        Object mO970 = new Object();
+        Object mO971 = new Object();
+        Object mO972 = new Object();
+        Object mO973 = new Object();
+        Object mO974 = new Object();
+        Object mO975 = new Object();
+        Object mO976 = new Object();
+        Object mO977 = new Object();
+        Object mO978 = new Object();
+        Object mO979 = new Object();
+        Object mO980 = new Object();
+        Object mO981 = new Object();
+        Object mO982 = new Object();
+        Object mO983 = new Object();
+        Object mO984 = new Object();
+        Object mO985 = new Object();
+        Object mO986 = new Object();
+        Object mO987 = new Object();
+        Object mO988 = new Object();
+        Object mO989 = new Object();
+        Object mO990 = new Object();
+        Object mO991 = new Object();
+        Object mO992 = new Object();
+        Object mO993 = new Object();
+        Object mO994 = new Object();
+        Object mO995 = new Object();
+        Object mO996 = new Object();
+        Object mO997 = new Object();
+        Object mO998 = new Object();
+        Object mO999 = new Object();
+    }
+
+    static class Deep0 {}
+
+    static class Deep1 extends Deep0 {}
+
+    static class Deep2 extends Deep1 {}
+
+    static class Deep3 extends Deep2 {}
+
+    static class Deep4 extends Deep3 {}
+
+    static class Deep5 extends Deep4 {}
+
+    static class Deep6 extends Deep5 {}
+
+    static class Deep7 extends Deep6 {}
+
+    static class Deep8 extends Deep7 {}
+
+    static class Deep9 extends Deep8 {}
+
+    static class Deep10 extends Deep9 {}
+
+    static class Deep11 extends Deep10 {}
+
+    static class Deep12 extends Deep11 {}
+
+    static class Deep13 extends Deep12 {}
+
+    static class Deep14 extends Deep13 {}
+
+    static class Deep15 extends Deep14 {}
+
+    static class Deep16 extends Deep15 {}
+
+    static class Deep17 extends Deep16 {}
+
+    static class Deep18 extends Deep17 {}
+
+    static class Deep19 extends Deep18 {}
+
+    static class Deep20 extends Deep19 {}
+
+    static class Deep21 extends Deep20 {}
+
+    static class Deep22 extends Deep21 {}
+
+    static class Deep23 extends Deep22 {}
+
+    static class Deep24 extends Deep23 {}
+
+    static class Deep25 extends Deep24 {}
+
+    static class Deep26 extends Deep25 {}
+
+    static class Deep27 extends Deep26 {}
+
+    static class Deep28 extends Deep27 {}
+
+    static class Deep29 extends Deep28 {}
+
+    static class Deep30 extends Deep29 {}
+
+    static class Deep31 extends Deep30 {}
+
+    static class Deep32 extends Deep31 {}
+
+    static class Deep33 extends Deep32 {}
+
+    static class Deep34 extends Deep33 {}
+
+    static class Deep35 extends Deep34 {}
+
+    static class Deep36 extends Deep35 {}
+
+    static class Deep37 extends Deep36 {}
+
+    static class Deep38 extends Deep37 {}
+
+    static class Deep39 extends Deep38 {}
+
+    static class Deep40 extends Deep39 {}
+
+    static class Deep41 extends Deep40 {}
+
+    static class Deep42 extends Deep41 {}
+
+    static class Deep43 extends Deep42 {}
+
+    static class Deep44 extends Deep43 {}
+
+    static class Deep45 extends Deep44 {}
+
+    static class Deep46 extends Deep45 {}
+
+    static class Deep47 extends Deep46 {}
+
+    static class Deep48 extends Deep47 {}
+
+    static class Deep49 extends Deep48 {}
+
+    static class Deep50 extends Deep49 {}
+
+    static class Deep51 extends Deep50 {}
+
+    static class Deep52 extends Deep51 {}
+
+    static class Deep53 extends Deep52 {}
+
+    static class Deep54 extends Deep53 {}
+
+    static class Deep55 extends Deep54 {}
+
+    static class Deep56 extends Deep55 {}
+
+    static class Deep57 extends Deep56 {}
+
+    static class Deep58 extends Deep57 {}
+
+    static class Deep59 extends Deep58 {}
+
+    static class Deep60 extends Deep59 {}
+
+    static class Deep61 extends Deep60 {}
+
+    static class Deep62 extends Deep61 {}
+
+    static class Deep63 extends Deep62 {}
+
+    static class Deep64 extends Deep63 {}
+
+    static class Deep65 extends Deep64 {}
+
+    static class Deep66 extends Deep65 {}
+
+    static class Deep67 extends Deep66 {}
+
+    static class Deep68 extends Deep67 {}
+
+    static class Deep69 extends Deep68 {}
+
+    static class Deep70 extends Deep69 {}
+
+    static class Deep71 extends Deep70 {}
+
+    static class Deep72 extends Deep71 {}
+
+    static class Deep73 extends Deep72 {}
+
+    static class Deep74 extends Deep73 {}
+
+    static class Deep75 extends Deep74 {}
+
+    static class Deep76 extends Deep75 {}
+
+    static class Deep77 extends Deep76 {}
+
+    static class Deep78 extends Deep77 {}
+
+    static class Deep79 extends Deep78 {}
+
+    static class Deep80 extends Deep79 {}
+
+    static class Deep81 extends Deep80 {}
+
+    static class Deep82 extends Deep81 {}
+
+    static class Deep83 extends Deep82 {}
+
+    static class Deep84 extends Deep83 {}
+
+    static class Deep85 extends Deep84 {}
+
+    static class Deep86 extends Deep85 {}
+
+    static class Deep87 extends Deep86 {}
+
+    static class Deep88 extends Deep87 {}
+
+    static class Deep89 extends Deep88 {}
+
+    static class Deep90 extends Deep89 {}
+
+    static class Deep91 extends Deep90 {}
+
+    static class Deep92 extends Deep91 {}
+
+    static class Deep93 extends Deep92 {}
+
+    static class Deep94 extends Deep93 {}
+
+    static class Deep95 extends Deep94 {}
+
+    static class Deep96 extends Deep95 {}
+
+    static class Deep97 extends Deep96 {}
+
+    static class Deep98 extends Deep97 {}
+
+    static class Deep99 extends Deep98 {}
+
+    static class Deep100 extends Deep99 {}
+
+    static class DeepCloneable extends Deep100 implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+    }
+
+    @Test
+    public void time_Object_clone() {
+        try {
+            CloneableObject o = new CloneableObject();
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+            while (state.keepRunning()) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    @Test
+    public void time_Object_manyFieldClone() {
+        try {
+            CloneableManyFieldObject o = new CloneableManyFieldObject();
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+            while (state.keepRunning()) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    @Test
+    public void time_Object_deepClone() {
+        try {
+            DeepCloneable o = new DeepCloneable();
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+            while (state.keepRunning()) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    @Test
+    public void time_Array_clone() {
+        int[] o = new int[32];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            o.clone();
+        }
+    }
+
+    @Test
+    public void time_ObjectArray_smallClone() {
+        Object[] o = new Object[32];
+        for (int i = 0; i < o.length / 2; ++i) {
+            o[i] = new Object();
+        }
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            o.clone();
+        }
+    }
+
+    @Test
+    public void time_ObjectArray_largeClone() {
+        Object[] o = new Object[2048];
+        for (int i = 0; i < o.length / 2; ++i) {
+            o[i] = new Object();
+        }
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            o.clone();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java
new file mode 100644
index 0000000..3f4f6af
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class DeepArrayOpsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private Object[] mArray;
+    private Object[] mArray2;
+
+    @Parameterized.Parameter(0)
+    public int mArrayLength;
+
+    @Parameterized.Parameters(name = "mArrayLength({0})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{1}, {4}, {16}, {32}, {2048}});
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mArray = new Object[mArrayLength * 14];
+        mArray2 = new Object[mArrayLength * 14];
+        for (int i = 0; i < mArrayLength; i += 14) {
+            mArray[i] = new IntWrapper(i);
+            mArray2[i] = new IntWrapper(i);
+
+            mArray[i + 1] = new16ElementObjectmArray();
+            mArray2[i + 1] = new16ElementObjectmArray();
+
+            mArray[i + 2] = new boolean[16];
+            mArray2[i + 2] = new boolean[16];
+
+            mArray[i + 3] = new byte[16];
+            mArray2[i + 3] = new byte[16];
+
+            mArray[i + 4] = new char[16];
+            mArray2[i + 4] = new char[16];
+
+            mArray[i + 5] = new short[16];
+            mArray2[i + 5] = new short[16];
+
+            mArray[i + 6] = new float[16];
+            mArray2[i + 6] = new float[16];
+
+            mArray[i + 7] = new long[16];
+            mArray2[i + 7] = new long[16];
+
+            mArray[i + 8] = new int[16];
+            mArray2[i + 8] = new int[16];
+
+            mArray[i + 9] = new double[16];
+            mArray2[i + 9] = new double[16];
+
+            // SubmArray types are concrete objects.
+            mArray[i + 10] = new16ElementArray(String.class, String.class);
+            mArray2[i + 10] = new16ElementArray(String.class, String.class);
+
+            mArray[i + 11] = new16ElementArray(Integer.class, Integer.class);
+            mArray2[i + 11] = new16ElementArray(Integer.class, Integer.class);
+
+            // SubmArray types is an interface.
+            mArray[i + 12] = new16ElementArray(CharSequence.class, String.class);
+            mArray2[i + 12] = new16ElementArray(CharSequence.class, String.class);
+
+            mArray[i + 13] = null;
+            mArray2[i + 13] = null;
+        }
+    }
+
+    @Test
+    public void deepHashCode() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Arrays.deepHashCode(mArray);
+        }
+    }
+
+    @Test
+    public void deepEquals() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Arrays.deepEquals(mArray, mArray2);
+        }
+    }
+
+    private static Object[] new16ElementObjectmArray() {
+        Object[] array = new Object[16];
+        for (int i = 0; i < 16; ++i) {
+            array[i] = new IntWrapper(i);
+        }
+
+        return array;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T, V> T[] new16ElementArray(Class<T> mArrayType, Class<V> type)
+            throws Exception {
+        T[] array = (T[]) Array.newInstance(type, 16);
+        if (!mArrayType.isAssignableFrom(type)) {
+            throw new IllegalArgumentException(mArrayType + " is not assignable from " + type);
+        }
+
+        Constructor<V> constructor = type.getDeclaredConstructor(String.class);
+        for (int i = 0; i < 16; ++i) {
+            array[i] = (T) constructor.newInstance(String.valueOf(i + 1000));
+        }
+
+        return array;
+    }
+
+    /**
+     * A class that provides very basic equals() and hashCode() operations and doesn't resort to
+     * memoization tricks like {@link java.lang.Integer}.
+     *
+     * <p>Useful for providing equal objects that aren't the same (a.equals(b) but a != b).
+     */
+    public static final class IntWrapper {
+        private final int mWrapped;
+
+        public IntWrapper(int wrap) {
+            mWrapped = wrap;
+        }
+
+        @Override
+        public int hashCode() {
+            return mWrapped;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof IntWrapper)) {
+                return false;
+            }
+
+            return ((IntWrapper) o).mWrapped == this.mWrapped;
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java
new file mode 100644
index 0000000..da94ae1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** What does field access cost? */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class FieldAccessPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static class Inner {
+        public int mPublicInnerIntVal;
+        protected int mProtectedInnerIntVal;
+        private int mPrivateInnerIntVal;
+        int mPackageInnerIntVal;
+    }
+
+    int mIntVal = 42;
+    final int mFinalIntVal = 42;
+    static int sStaticIntVal = 42;
+    static final int FINAL_INT_VAL = 42;
+
+    @Test
+    public void timeField() {
+        int result = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = mIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldFinal() {
+        int result = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = mFinalIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldStatic() {
+        int result = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = sStaticIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldStaticFinal() {
+        int result = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = FINAL_INT_VAL;
+        }
+    }
+
+    @Test
+    public void timeFieldCached() {
+        int result = 0;
+        int cachedIntVal = this.mIntVal;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = cachedIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldPrivateInnerClassPublicField() {
+        int result = 0;
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = inner.mPublicInnerIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldPrivateInnerClassProtectedField() {
+        int result = 0;
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = inner.mProtectedInnerIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldPrivateInnerClassPrivateField() {
+        int result = 0;
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = inner.mPrivateInnerIntVal;
+        }
+    }
+
+    @Test
+    public void timeFieldPrivateInnerClassPackageField() {
+        int result = 0;
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = inner.mPackageInnerIntVal;
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java
new file mode 100644
index 0000000..9446d99c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** How do the various hash maps compare? */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class HashedCollectionsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeHashMapGet() {
+        HashMap<String, String> map = new HashMap<String, String>();
+        map.put("hello", "world");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.get("hello");
+        }
+    }
+
+    @Test
+    public void timeHashMapGet_Synchronized() {
+        HashMap<String, String> map = new HashMap<String, String>();
+        synchronized (map) {
+            map.put("hello", "world");
+        }
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            synchronized (map) {
+                map.get("hello");
+            }
+        }
+    }
+
+    @Test
+    public void timeHashtableGet() {
+        Hashtable<String, String> map = new Hashtable<String, String>();
+        map.put("hello", "world");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.get("hello");
+        }
+    }
+
+    @Test
+    public void timeLinkedHashMapGet() {
+        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
+        map.put("hello", "world");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.get("hello");
+        }
+    }
+
+    @Test
+    public void timeConcurrentHashMapGet() {
+        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
+        map.put("hello", "world");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.get("hello");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java
new file mode 100644
index 0000000..be2a7e9
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java
@@ -0,0 +1,1818 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * This file is script-generated by ImtConflictPerfTestGen.py. It measures the performance impact of
+ * conflicts in interface method tables. Run `python ImtConflictPerfTestGen.py >
+ * ImtConflictPerfTest.java` to regenerate.
+ *
+ * <p>Each interface has 64 methods, which is the current size of an IMT. C0 implements one
+ * interface, C1 implements two, C2 implements three, and so on. The intent is that C0 has no
+ * conflicts in its IMT, C1 has depth-2 conflicts in its IMT, C2 has depth-3 conflicts, etc. This is
+ * currently guaranteed by the fact that we hash interface methods by taking their method index
+ * modulo 64. (Note that a "conflict depth" of 1 means no conflict at all.)
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ImtConflictPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Before
+    public void setup() {
+        C0 c0 = new C0();
+        callF0(c0);
+        C1 c1 = new C1();
+        callF0(c1);
+        callF19(c1);
+        C2 c2 = new C2();
+        callF0(c2);
+        callF19(c2);
+        callF38(c2);
+        C3 c3 = new C3();
+        callF0(c3);
+        callF19(c3);
+        callF38(c3);
+        callF57(c3);
+        C4 c4 = new C4();
+        callF0(c4);
+        callF19(c4);
+        callF38(c4);
+        callF57(c4);
+        callF76(c4);
+        C5 c5 = new C5();
+        callF0(c5);
+        callF19(c5);
+        callF38(c5);
+        callF57(c5);
+        callF76(c5);
+        callF95(c5);
+        C6 c6 = new C6();
+        callF0(c6);
+        callF19(c6);
+        callF38(c6);
+        callF57(c6);
+        callF76(c6);
+        callF95(c6);
+        callF114(c6);
+        C7 c7 = new C7();
+        callF0(c7);
+        callF19(c7);
+        callF38(c7);
+        callF57(c7);
+        callF76(c7);
+        callF95(c7);
+        callF114(c7);
+        callF133(c7);
+        C8 c8 = new C8();
+        callF0(c8);
+        callF19(c8);
+        callF38(c8);
+        callF57(c8);
+        callF76(c8);
+        callF95(c8);
+        callF114(c8);
+        callF133(c8);
+        callF152(c8);
+        C9 c9 = new C9();
+        callF0(c9);
+        callF19(c9);
+        callF38(c9);
+        callF57(c9);
+        callF76(c9);
+        callF95(c9);
+        callF114(c9);
+        callF133(c9);
+        callF152(c9);
+        callF171(c9);
+        C10 c10 = new C10();
+        callF0(c10);
+        callF19(c10);
+        callF38(c10);
+        callF57(c10);
+        callF76(c10);
+        callF95(c10);
+        callF114(c10);
+        callF133(c10);
+        callF152(c10);
+        callF171(c10);
+        callF190(c10);
+        C11 c11 = new C11();
+        callF0(c11);
+        callF19(c11);
+        callF38(c11);
+        callF57(c11);
+        callF76(c11);
+        callF95(c11);
+        callF114(c11);
+        callF133(c11);
+        callF152(c11);
+        callF171(c11);
+        callF190(c11);
+        callF209(c11);
+        C12 c12 = new C12();
+        callF0(c12);
+        callF19(c12);
+        callF38(c12);
+        callF57(c12);
+        callF76(c12);
+        callF95(c12);
+        callF114(c12);
+        callF133(c12);
+        callF152(c12);
+        callF171(c12);
+        callF190(c12);
+        callF209(c12);
+        callF228(c12);
+        C13 c13 = new C13();
+        callF0(c13);
+        callF19(c13);
+        callF38(c13);
+        callF57(c13);
+        callF76(c13);
+        callF95(c13);
+        callF114(c13);
+        callF133(c13);
+        callF152(c13);
+        callF171(c13);
+        callF190(c13);
+        callF209(c13);
+        callF228(c13);
+        callF247(c13);
+        C14 c14 = new C14();
+        callF0(c14);
+        callF19(c14);
+        callF38(c14);
+        callF57(c14);
+        callF76(c14);
+        callF95(c14);
+        callF114(c14);
+        callF133(c14);
+        callF152(c14);
+        callF171(c14);
+        callF190(c14);
+        callF209(c14);
+        callF228(c14);
+        callF247(c14);
+        callF266(c14);
+        C15 c15 = new C15();
+        callF0(c15);
+        callF19(c15);
+        callF38(c15);
+        callF57(c15);
+        callF76(c15);
+        callF95(c15);
+        callF114(c15);
+        callF133(c15);
+        callF152(c15);
+        callF171(c15);
+        callF190(c15);
+        callF209(c15);
+        callF228(c15);
+        callF247(c15);
+        callF266(c15);
+        callF285(c15);
+        C16 c16 = new C16();
+        callF0(c16);
+        callF19(c16);
+        callF38(c16);
+        callF57(c16);
+        callF76(c16);
+        callF95(c16);
+        callF114(c16);
+        callF133(c16);
+        callF152(c16);
+        callF171(c16);
+        callF190(c16);
+        callF209(c16);
+        callF228(c16);
+        callF247(c16);
+        callF266(c16);
+        callF285(c16);
+        callF304(c16);
+        C17 c17 = new C17();
+        callF0(c17);
+        callF19(c17);
+        callF38(c17);
+        callF57(c17);
+        callF76(c17);
+        callF95(c17);
+        callF114(c17);
+        callF133(c17);
+        callF152(c17);
+        callF171(c17);
+        callF190(c17);
+        callF209(c17);
+        callF228(c17);
+        callF247(c17);
+        callF266(c17);
+        callF285(c17);
+        callF304(c17);
+        callF323(c17);
+        C18 c18 = new C18();
+        callF0(c18);
+        callF19(c18);
+        callF38(c18);
+        callF57(c18);
+        callF76(c18);
+        callF95(c18);
+        callF114(c18);
+        callF133(c18);
+        callF152(c18);
+        callF171(c18);
+        callF190(c18);
+        callF209(c18);
+        callF228(c18);
+        callF247(c18);
+        callF266(c18);
+        callF285(c18);
+        callF304(c18);
+        callF323(c18);
+        callF342(c18);
+        C19 c19 = new C19();
+        callF0(c19);
+        callF19(c19);
+        callF38(c19);
+        callF57(c19);
+        callF76(c19);
+        callF95(c19);
+        callF114(c19);
+        callF133(c19);
+        callF152(c19);
+        callF171(c19);
+        callF190(c19);
+        callF209(c19);
+        callF228(c19);
+        callF247(c19);
+        callF266(c19);
+        callF285(c19);
+        callF304(c19);
+        callF323(c19);
+        callF342(c19);
+        callF361(c19);
+    }
+
+    @Test
+    public void timeConflictDepth01() {
+        C0 c0 = new C0();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+            callF0(c0);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth02() {
+        C1 c1 = new C1();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+            callF0(c1);
+            callF19(c1);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth03() {
+        C2 c2 = new C2();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+            callF38(c2);
+            callF0(c2);
+            callF19(c2);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth04() {
+        C3 c3 = new C3();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c3);
+            callF19(c3);
+            callF38(c3);
+            callF57(c3);
+            callF0(c3);
+            callF19(c3);
+            callF38(c3);
+            callF57(c3);
+            callF0(c3);
+            callF19(c3);
+            callF38(c3);
+            callF57(c3);
+            callF0(c3);
+            callF19(c3);
+            callF38(c3);
+            callF57(c3);
+            callF0(c3);
+            callF19(c3);
+            callF38(c3);
+            callF57(c3);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth05() {
+        C4 c4 = new C4();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c4);
+            callF19(c4);
+            callF38(c4);
+            callF57(c4);
+            callF76(c4);
+            callF0(c4);
+            callF19(c4);
+            callF38(c4);
+            callF57(c4);
+            callF76(c4);
+            callF0(c4);
+            callF19(c4);
+            callF38(c4);
+            callF57(c4);
+            callF76(c4);
+            callF0(c4);
+            callF19(c4);
+            callF38(c4);
+            callF57(c4);
+            callF76(c4);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth06() {
+        C5 c5 = new C5();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c5);
+            callF19(c5);
+            callF38(c5);
+            callF57(c5);
+            callF76(c5);
+            callF95(c5);
+            callF0(c5);
+            callF19(c5);
+            callF38(c5);
+            callF57(c5);
+            callF76(c5);
+            callF95(c5);
+            callF0(c5);
+            callF19(c5);
+            callF38(c5);
+            callF57(c5);
+            callF76(c5);
+            callF95(c5);
+            callF0(c5);
+            callF19(c5);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth07() {
+        C6 c6 = new C6();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c6);
+            callF19(c6);
+            callF38(c6);
+            callF57(c6);
+            callF76(c6);
+            callF95(c6);
+            callF114(c6);
+            callF0(c6);
+            callF19(c6);
+            callF38(c6);
+            callF57(c6);
+            callF76(c6);
+            callF95(c6);
+            callF114(c6);
+            callF0(c6);
+            callF19(c6);
+            callF38(c6);
+            callF57(c6);
+            callF76(c6);
+            callF95(c6);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth08() {
+        C7 c7 = new C7();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c7);
+            callF19(c7);
+            callF38(c7);
+            callF57(c7);
+            callF76(c7);
+            callF95(c7);
+            callF114(c7);
+            callF133(c7);
+            callF0(c7);
+            callF19(c7);
+            callF38(c7);
+            callF57(c7);
+            callF76(c7);
+            callF95(c7);
+            callF114(c7);
+            callF133(c7);
+            callF0(c7);
+            callF19(c7);
+            callF38(c7);
+            callF57(c7);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth09() {
+        C8 c8 = new C8();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c8);
+            callF19(c8);
+            callF38(c8);
+            callF57(c8);
+            callF76(c8);
+            callF95(c8);
+            callF114(c8);
+            callF133(c8);
+            callF152(c8);
+            callF0(c8);
+            callF19(c8);
+            callF38(c8);
+            callF57(c8);
+            callF76(c8);
+            callF95(c8);
+            callF114(c8);
+            callF133(c8);
+            callF152(c8);
+            callF0(c8);
+            callF19(c8);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth10() {
+        C9 c9 = new C9();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c9);
+            callF19(c9);
+            callF38(c9);
+            callF57(c9);
+            callF76(c9);
+            callF95(c9);
+            callF114(c9);
+            callF133(c9);
+            callF152(c9);
+            callF171(c9);
+            callF0(c9);
+            callF19(c9);
+            callF38(c9);
+            callF57(c9);
+            callF76(c9);
+            callF95(c9);
+            callF114(c9);
+            callF133(c9);
+            callF152(c9);
+            callF171(c9);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth11() {
+        C10 c10 = new C10();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c10);
+            callF19(c10);
+            callF38(c10);
+            callF57(c10);
+            callF76(c10);
+            callF95(c10);
+            callF114(c10);
+            callF133(c10);
+            callF152(c10);
+            callF171(c10);
+            callF190(c10);
+            callF0(c10);
+            callF19(c10);
+            callF38(c10);
+            callF57(c10);
+            callF76(c10);
+            callF95(c10);
+            callF114(c10);
+            callF133(c10);
+            callF152(c10);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth12() {
+        C11 c11 = new C11();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c11);
+            callF19(c11);
+            callF38(c11);
+            callF57(c11);
+            callF76(c11);
+            callF95(c11);
+            callF114(c11);
+            callF133(c11);
+            callF152(c11);
+            callF171(c11);
+            callF190(c11);
+            callF209(c11);
+            callF0(c11);
+            callF19(c11);
+            callF38(c11);
+            callF57(c11);
+            callF76(c11);
+            callF95(c11);
+            callF114(c11);
+            callF133(c11);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth13() {
+        C12 c12 = new C12();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c12);
+            callF19(c12);
+            callF38(c12);
+            callF57(c12);
+            callF76(c12);
+            callF95(c12);
+            callF114(c12);
+            callF133(c12);
+            callF152(c12);
+            callF171(c12);
+            callF190(c12);
+            callF209(c12);
+            callF228(c12);
+            callF0(c12);
+            callF19(c12);
+            callF38(c12);
+            callF57(c12);
+            callF76(c12);
+            callF95(c12);
+            callF114(c12);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth14() {
+        C13 c13 = new C13();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c13);
+            callF19(c13);
+            callF38(c13);
+            callF57(c13);
+            callF76(c13);
+            callF95(c13);
+            callF114(c13);
+            callF133(c13);
+            callF152(c13);
+            callF171(c13);
+            callF190(c13);
+            callF209(c13);
+            callF228(c13);
+            callF247(c13);
+            callF0(c13);
+            callF19(c13);
+            callF38(c13);
+            callF57(c13);
+            callF76(c13);
+            callF95(c13);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth15() {
+        C14 c14 = new C14();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c14);
+            callF19(c14);
+            callF38(c14);
+            callF57(c14);
+            callF76(c14);
+            callF95(c14);
+            callF114(c14);
+            callF133(c14);
+            callF152(c14);
+            callF171(c14);
+            callF190(c14);
+            callF209(c14);
+            callF228(c14);
+            callF247(c14);
+            callF266(c14);
+            callF0(c14);
+            callF19(c14);
+            callF38(c14);
+            callF57(c14);
+            callF76(c14);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth16() {
+        C15 c15 = new C15();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c15);
+            callF19(c15);
+            callF38(c15);
+            callF57(c15);
+            callF76(c15);
+            callF95(c15);
+            callF114(c15);
+            callF133(c15);
+            callF152(c15);
+            callF171(c15);
+            callF190(c15);
+            callF209(c15);
+            callF228(c15);
+            callF247(c15);
+            callF266(c15);
+            callF285(c15);
+            callF0(c15);
+            callF19(c15);
+            callF38(c15);
+            callF57(c15);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth17() {
+        C16 c16 = new C16();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c16);
+            callF19(c16);
+            callF38(c16);
+            callF57(c16);
+            callF76(c16);
+            callF95(c16);
+            callF114(c16);
+            callF133(c16);
+            callF152(c16);
+            callF171(c16);
+            callF190(c16);
+            callF209(c16);
+            callF228(c16);
+            callF247(c16);
+            callF266(c16);
+            callF285(c16);
+            callF304(c16);
+            callF0(c16);
+            callF19(c16);
+            callF38(c16);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth18() {
+        C17 c17 = new C17();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c17);
+            callF19(c17);
+            callF38(c17);
+            callF57(c17);
+            callF76(c17);
+            callF95(c17);
+            callF114(c17);
+            callF133(c17);
+            callF152(c17);
+            callF171(c17);
+            callF190(c17);
+            callF209(c17);
+            callF228(c17);
+            callF247(c17);
+            callF266(c17);
+            callF285(c17);
+            callF304(c17);
+            callF323(c17);
+            callF0(c17);
+            callF19(c17);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth19() {
+        C18 c18 = new C18();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c18);
+            callF19(c18);
+            callF38(c18);
+            callF57(c18);
+            callF76(c18);
+            callF95(c18);
+            callF114(c18);
+            callF133(c18);
+            callF152(c18);
+            callF171(c18);
+            callF190(c18);
+            callF209(c18);
+            callF228(c18);
+            callF247(c18);
+            callF266(c18);
+            callF285(c18);
+            callF304(c18);
+            callF323(c18);
+            callF342(c18);
+            callF0(c18);
+        }
+    }
+
+    @Test
+    public void timeConflictDepth20() {
+        C19 c19 = new C19();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            callF0(c19);
+            callF19(c19);
+            callF38(c19);
+            callF57(c19);
+            callF76(c19);
+            callF95(c19);
+            callF114(c19);
+            callF133(c19);
+            callF152(c19);
+            callF171(c19);
+            callF190(c19);
+            callF209(c19);
+            callF228(c19);
+            callF247(c19);
+            callF266(c19);
+            callF285(c19);
+            callF304(c19);
+            callF323(c19);
+            callF342(c19);
+            callF361(c19);
+        }
+    }
+
+    public void callF0(I0 i) {
+        i.f0();
+    }
+
+    public void callF19(I1 i) {
+        i.f19();
+    }
+
+    public void callF38(I2 i) {
+        i.f38();
+    }
+
+    public void callF57(I3 i) {
+        i.f57();
+    }
+
+    public void callF76(I4 i) {
+        i.f76();
+    }
+
+    public void callF95(I5 i) {
+        i.f95();
+    }
+
+    public void callF114(I6 i) {
+        i.f114();
+    }
+
+    public void callF133(I7 i) {
+        i.f133();
+    }
+
+    public void callF152(I8 i) {
+        i.f152();
+    }
+
+    public void callF171(I9 i) {
+        i.f171();
+    }
+
+    public void callF190(I10 i) {
+        i.f190();
+    }
+
+    public void callF209(I11 i) {
+        i.f209();
+    }
+
+    public void callF228(I12 i) {
+        i.f228();
+    }
+
+    public void callF247(I13 i) {
+        i.f247();
+    }
+
+    public void callF266(I14 i) {
+        i.f266();
+    }
+
+    public void callF285(I15 i) {
+        i.f285();
+    }
+
+    public void callF304(I16 i) {
+        i.f304();
+    }
+
+    public void callF323(I17 i) {
+        i.f323();
+    }
+
+    public void callF342(I18 i) {
+        i.f342();
+    }
+
+    public void callF361(I19 i) {
+        i.f361();
+    }
+
+    static class C0 implements I0 {}
+
+    static class C1 implements I0, I1 {}
+
+    static class C2 implements I0, I1, I2 {}
+
+    static class C3 implements I0, I1, I2, I3 {}
+
+    static class C4 implements I0, I1, I2, I3, I4 {}
+
+    static class C5 implements I0, I1, I2, I3, I4, I5 {}
+
+    static class C6 implements I0, I1, I2, I3, I4, I5, I6 {}
+
+    static class C7 implements I0, I1, I2, I3, I4, I5, I6, I7 {}
+
+    static class C8 implements I0, I1, I2, I3, I4, I5, I6, I7, I8 {}
+
+    static class C9 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9 {}
+
+    static class C10 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10 {}
+
+    static class C11 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11 {}
+
+    static class C12 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12 {}
+
+    static class C13 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13 {}
+
+    static class C14 implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14 {}
+
+    static class C15
+            implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15 {}
+
+    static class C16
+            implements I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16 {}
+
+    static class C17
+            implements I0,
+                    I1,
+                    I2,
+                    I3,
+                    I4,
+                    I5,
+                    I6,
+                    I7,
+                    I8,
+                    I9,
+                    I10,
+                    I11,
+                    I12,
+                    I13,
+                    I14,
+                    I15,
+                    I16,
+                    I17 {}
+
+    static class C18
+            implements I0,
+                    I1,
+                    I2,
+                    I3,
+                    I4,
+                    I5,
+                    I6,
+                    I7,
+                    I8,
+                    I9,
+                    I10,
+                    I11,
+                    I12,
+                    I13,
+                    I14,
+                    I15,
+                    I16,
+                    I17,
+                    I18 {}
+
+    static class C19
+            implements I0,
+                    I1,
+                    I2,
+                    I3,
+                    I4,
+                    I5,
+                    I6,
+                    I7,
+                    I8,
+                    I9,
+                    I10,
+                    I11,
+                    I12,
+                    I13,
+                    I14,
+                    I15,
+                    I16,
+                    I17,
+                    I18,
+                    I19 {}
+
+    interface I0 {
+        default void f0() {}
+
+        default void f1() {}
+
+        default void f2() {}
+
+        default void f3() {}
+
+        default void f4() {}
+
+        default void f5() {}
+
+        default void f6() {}
+
+        default void f7() {}
+
+        default void f8() {}
+
+        default void f9() {}
+
+        default void f10() {}
+
+        default void f11() {}
+
+        default void f12() {}
+
+        default void f13() {}
+
+        default void f14() {}
+
+        default void f15() {}
+
+        default void f16() {}
+
+        default void f17() {}
+
+        default void f18() {}
+    }
+
+    interface I1 {
+        default void f19() {}
+
+        default void f20() {}
+
+        default void f21() {}
+
+        default void f22() {}
+
+        default void f23() {}
+
+        default void f24() {}
+
+        default void f25() {}
+
+        default void f26() {}
+
+        default void f27() {}
+
+        default void f28() {}
+
+        default void f29() {}
+
+        default void f30() {}
+
+        default void f31() {}
+
+        default void f32() {}
+
+        default void f33() {}
+
+        default void f34() {}
+
+        default void f35() {}
+
+        default void f36() {}
+
+        default void f37() {}
+    }
+
+    interface I2 {
+        default void f38() {}
+
+        default void f39() {}
+
+        default void f40() {}
+
+        default void f41() {}
+
+        default void f42() {}
+
+        default void f43() {}
+
+        default void f44() {}
+
+        default void f45() {}
+
+        default void f46() {}
+
+        default void f47() {}
+
+        default void f48() {}
+
+        default void f49() {}
+
+        default void f50() {}
+
+        default void f51() {}
+
+        default void f52() {}
+
+        default void f53() {}
+
+        default void f54() {}
+
+        default void f55() {}
+
+        default void f56() {}
+    }
+
+    interface I3 {
+        default void f57() {}
+
+        default void f58() {}
+
+        default void f59() {}
+
+        default void f60() {}
+
+        default void f61() {}
+
+        default void f62() {}
+
+        default void f63() {}
+
+        default void f64() {}
+
+        default void f65() {}
+
+        default void f66() {}
+
+        default void f67() {}
+
+        default void f68() {}
+
+        default void f69() {}
+
+        default void f70() {}
+
+        default void f71() {}
+
+        default void f72() {}
+
+        default void f73() {}
+
+        default void f74() {}
+
+        default void f75() {}
+    }
+
+    interface I4 {
+        default void f76() {}
+
+        default void f77() {}
+
+        default void f78() {}
+
+        default void f79() {}
+
+        default void f80() {}
+
+        default void f81() {}
+
+        default void f82() {}
+
+        default void f83() {}
+
+        default void f84() {}
+
+        default void f85() {}
+
+        default void f86() {}
+
+        default void f87() {}
+
+        default void f88() {}
+
+        default void f89() {}
+
+        default void f90() {}
+
+        default void f91() {}
+
+        default void f92() {}
+
+        default void f93() {}
+
+        default void f94() {}
+    }
+
+    interface I5 {
+        default void f95() {}
+
+        default void f96() {}
+
+        default void f97() {}
+
+        default void f98() {}
+
+        default void f99() {}
+
+        default void f100() {}
+
+        default void f101() {}
+
+        default void f102() {}
+
+        default void f103() {}
+
+        default void f104() {}
+
+        default void f105() {}
+
+        default void f106() {}
+
+        default void f107() {}
+
+        default void f108() {}
+
+        default void f109() {}
+
+        default void f110() {}
+
+        default void f111() {}
+
+        default void f112() {}
+
+        default void f113() {}
+    }
+
+    interface I6 {
+        default void f114() {}
+
+        default void f115() {}
+
+        default void f116() {}
+
+        default void f117() {}
+
+        default void f118() {}
+
+        default void f119() {}
+
+        default void f120() {}
+
+        default void f121() {}
+
+        default void f122() {}
+
+        default void f123() {}
+
+        default void f124() {}
+
+        default void f125() {}
+
+        default void f126() {}
+
+        default void f127() {}
+
+        default void f128() {}
+
+        default void f129() {}
+
+        default void f130() {}
+
+        default void f131() {}
+
+        default void f132() {}
+    }
+
+    interface I7 {
+        default void f133() {}
+
+        default void f134() {}
+
+        default void f135() {}
+
+        default void f136() {}
+
+        default void f137() {}
+
+        default void f138() {}
+
+        default void f139() {}
+
+        default void f140() {}
+
+        default void f141() {}
+
+        default void f142() {}
+
+        default void f143() {}
+
+        default void f144() {}
+
+        default void f145() {}
+
+        default void f146() {}
+
+        default void f147() {}
+
+        default void f148() {}
+
+        default void f149() {}
+
+        default void f150() {}
+
+        default void f151() {}
+    }
+
+    interface I8 {
+        default void f152() {}
+
+        default void f153() {}
+
+        default void f154() {}
+
+        default void f155() {}
+
+        default void f156() {}
+
+        default void f157() {}
+
+        default void f158() {}
+
+        default void f159() {}
+
+        default void f160() {}
+
+        default void f161() {}
+
+        default void f162() {}
+
+        default void f163() {}
+
+        default void f164() {}
+
+        default void f165() {}
+
+        default void f166() {}
+
+        default void f167() {}
+
+        default void f168() {}
+
+        default void f169() {}
+
+        default void f170() {}
+    }
+
+    interface I9 {
+        default void f171() {}
+
+        default void f172() {}
+
+        default void f173() {}
+
+        default void f174() {}
+
+        default void f175() {}
+
+        default void f176() {}
+
+        default void f177() {}
+
+        default void f178() {}
+
+        default void f179() {}
+
+        default void f180() {}
+
+        default void f181() {}
+
+        default void f182() {}
+
+        default void f183() {}
+
+        default void f184() {}
+
+        default void f185() {}
+
+        default void f186() {}
+
+        default void f187() {}
+
+        default void f188() {}
+
+        default void f189() {}
+    }
+
+    interface I10 {
+        default void f190() {}
+
+        default void f191() {}
+
+        default void f192() {}
+
+        default void f193() {}
+
+        default void f194() {}
+
+        default void f195() {}
+
+        default void f196() {}
+
+        default void f197() {}
+
+        default void f198() {}
+
+        default void f199() {}
+
+        default void f200() {}
+
+        default void f201() {}
+
+        default void f202() {}
+
+        default void f203() {}
+
+        default void f204() {}
+
+        default void f205() {}
+
+        default void f206() {}
+
+        default void f207() {}
+
+        default void f208() {}
+    }
+
+    interface I11 {
+        default void f209() {}
+
+        default void f210() {}
+
+        default void f211() {}
+
+        default void f212() {}
+
+        default void f213() {}
+
+        default void f214() {}
+
+        default void f215() {}
+
+        default void f216() {}
+
+        default void f217() {}
+
+        default void f218() {}
+
+        default void f219() {}
+
+        default void f220() {}
+
+        default void f221() {}
+
+        default void f222() {}
+
+        default void f223() {}
+
+        default void f224() {}
+
+        default void f225() {}
+
+        default void f226() {}
+
+        default void f227() {}
+    }
+
+    interface I12 {
+        default void f228() {}
+
+        default void f229() {}
+
+        default void f230() {}
+
+        default void f231() {}
+
+        default void f232() {}
+
+        default void f233() {}
+
+        default void f234() {}
+
+        default void f235() {}
+
+        default void f236() {}
+
+        default void f237() {}
+
+        default void f238() {}
+
+        default void f239() {}
+
+        default void f240() {}
+
+        default void f241() {}
+
+        default void f242() {}
+
+        default void f243() {}
+
+        default void f244() {}
+
+        default void f245() {}
+
+        default void f246() {}
+    }
+
+    interface I13 {
+        default void f247() {}
+
+        default void f248() {}
+
+        default void f249() {}
+
+        default void f250() {}
+
+        default void f251() {}
+
+        default void f252() {}
+
+        default void f253() {}
+
+        default void f254() {}
+
+        default void f255() {}
+
+        default void f256() {}
+
+        default void f257() {}
+
+        default void f258() {}
+
+        default void f259() {}
+
+        default void f260() {}
+
+        default void f261() {}
+
+        default void f262() {}
+
+        default void f263() {}
+
+        default void f264() {}
+
+        default void f265() {}
+    }
+
+    interface I14 {
+        default void f266() {}
+
+        default void f267() {}
+
+        default void f268() {}
+
+        default void f269() {}
+
+        default void f270() {}
+
+        default void f271() {}
+
+        default void f272() {}
+
+        default void f273() {}
+
+        default void f274() {}
+
+        default void f275() {}
+
+        default void f276() {}
+
+        default void f277() {}
+
+        default void f278() {}
+
+        default void f279() {}
+
+        default void f280() {}
+
+        default void f281() {}
+
+        default void f282() {}
+
+        default void f283() {}
+
+        default void f284() {}
+    }
+
+    interface I15 {
+        default void f285() {}
+
+        default void f286() {}
+
+        default void f287() {}
+
+        default void f288() {}
+
+        default void f289() {}
+
+        default void f290() {}
+
+        default void f291() {}
+
+        default void f292() {}
+
+        default void f293() {}
+
+        default void f294() {}
+
+        default void f295() {}
+
+        default void f296() {}
+
+        default void f297() {}
+
+        default void f298() {}
+
+        default void f299() {}
+
+        default void f300() {}
+
+        default void f301() {}
+
+        default void f302() {}
+
+        default void f303() {}
+    }
+
+    interface I16 {
+        default void f304() {}
+
+        default void f305() {}
+
+        default void f306() {}
+
+        default void f307() {}
+
+        default void f308() {}
+
+        default void f309() {}
+
+        default void f310() {}
+
+        default void f311() {}
+
+        default void f312() {}
+
+        default void f313() {}
+
+        default void f314() {}
+
+        default void f315() {}
+
+        default void f316() {}
+
+        default void f317() {}
+
+        default void f318() {}
+
+        default void f319() {}
+
+        default void f320() {}
+
+        default void f321() {}
+
+        default void f322() {}
+    }
+
+    interface I17 {
+        default void f323() {}
+
+        default void f324() {}
+
+        default void f325() {}
+
+        default void f326() {}
+
+        default void f327() {}
+
+        default void f328() {}
+
+        default void f329() {}
+
+        default void f330() {}
+
+        default void f331() {}
+
+        default void f332() {}
+
+        default void f333() {}
+
+        default void f334() {}
+
+        default void f335() {}
+
+        default void f336() {}
+
+        default void f337() {}
+
+        default void f338() {}
+
+        default void f339() {}
+
+        default void f340() {}
+
+        default void f341() {}
+    }
+
+    interface I18 {
+        default void f342() {}
+
+        default void f343() {}
+
+        default void f344() {}
+
+        default void f345() {}
+
+        default void f346() {}
+
+        default void f347() {}
+
+        default void f348() {}
+
+        default void f349() {}
+
+        default void f350() {}
+
+        default void f351() {}
+
+        default void f352() {}
+
+        default void f353() {}
+
+        default void f354() {}
+
+        default void f355() {}
+
+        default void f356() {}
+
+        default void f357() {}
+
+        default void f358() {}
+
+        default void f359() {}
+
+        default void f360() {}
+    }
+
+    interface I19 {
+        default void f361() {}
+
+        default void f362() {}
+
+        default void f363() {}
+
+        default void f364() {}
+
+        default void f365() {}
+
+        default void f366() {}
+
+        default void f367() {}
+
+        default void f368() {}
+
+        default void f369() {}
+
+        default void f370() {}
+
+        default void f371() {}
+
+        default void f372() {}
+
+        default void f373() {}
+
+        default void f374() {}
+
+        default void f375() {}
+
+        default void f376() {}
+
+        default void f377() {}
+
+        default void f378() {}
+
+        default void f379() {}
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTestGen.py b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTestGen.py
new file mode 100755
index 0000000..eea3b84
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTestGen.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import sys
+
+max_conflict_depth = 20 # In practice does not go above 20 for reasonable IMT sizes
+try:
+    imt_size = int(sys.argv[1])
+except (IndexError, ValueError):
+    print("Usage: python ImtConflictPerfTestGen.py <IMT_SIZE>")
+    sys.exit(1)
+
+license = """\
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"""
+description = """
+/**
+ * This file is script-generated by ImtConflictPerfTestGen.py.
+ * It measures the performance impact of conflicts in interface method tables.
+ * Run `python ImtConflictPerfTestGen.py > ImtConflictPerfTest.java` to regenerate.
+ *
+ * Each interface has 64 methods, which is the current size of an IMT. C0 implements
+ * one interface, C1 implements two, C2 implements three, and so on. The intent
+ * is that C0 has no conflicts in its IMT, C1 has depth-2 conflicts in
+ * its IMT, C2 has depth-3 conflicts, etc. This is currently guaranteed by
+ * the fact that we hash interface methods by taking their method index modulo 64.
+ * (Note that a "conflict depth" of 1 means no conflict at all.)
+ */\
+"""
+
+print(license)
+print("package android.libcore;")
+imports = """
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+"""
+print(imports)
+print(description)
+
+print("@RunWith(AndroidJUnit4.class)")
+print("@LargeTest")
+print("public class ImtConflictPerfTest {")
+print("    @Rule")
+print("    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();")
+print("")
+# Warm up interface method tables
+print("    @Before")
+print("    public void setup() {")
+for i in range(max_conflict_depth):
+    print("        C{0} c{0} = new C{0}();".format(i))
+    for j in range(i+1):
+        print("        callF{}(c{});".format(imt_size * j, i))
+print("    }")
+
+# Print test cases--one for each conflict depth
+for i in range(max_conflict_depth):
+    print("    @Test")
+    print("    public void timeConflictDepth{:02d}() {{".format(i+1))
+    print("        C{0} c{0} = new C{0}();".format(i))
+    print("        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();")
+    print("        while (state.keepRunning()) {")
+    # Cycle through each interface method in an IMT entry in order
+    # to test all conflict resolution possibilities
+    for j in range(max_conflict_depth):
+        print("            callF{}(c{});".format(imt_size * (j % (i + 1)), i))
+    print("        }")
+    print("    }")
+
+# Make calls through the IMTs
+for i in range(max_conflict_depth):
+    print("    public void callF{0}(I{1} i) {{ i.f{0}(); }}".format(imt_size*i, i))
+
+# Class definitions, implementing varying amounts of interfaces
+for i in range(max_conflict_depth):
+    interfaces = ", ".join(["I{}".format(j) for j in range(i+1)])
+    print("    static class C{} implements {} {{}}".format(i, interfaces))
+
+# Interface definitions, each with enough methods to fill an entire IMT
+for i in range(max_conflict_depth):
+    print("    interface I{} {{".format(i))
+    for j in range(imt_size):
+        print("        default void f{}() {{}}".format(i*imt_size + j))
+    print("    }")
+
+print("}")
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java
new file mode 100644
index 0000000..ca99779
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Compares various kinds of method invocation. */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MethodInvocationPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    interface I {
+        void emptyInterface();
+    }
+
+    static class C implements I {
+        private int mField;
+
+        private int getField() {
+            return mField;
+        }
+
+        public void timeInternalGetter(BenchmarkState state) {
+            int result = 0;
+            while (state.keepRunning()) {
+                result = getField();
+            }
+        }
+
+        public void timeInternalFieldAccess(BenchmarkState state) {
+            int result = 0;
+            while (state.keepRunning()) {
+                result = mField;
+            }
+        }
+
+        public static void emptyStatic() {}
+
+        public void emptyVirtual() {}
+
+        public void emptyInterface() {}
+    }
+
+    public void timeInternalGetter() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        new C().timeInternalGetter(state);
+    }
+
+    public void timeInternalFieldAccess() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        new C().timeInternalFieldAccess(state);
+    }
+
+    // Test an intrinsic.
+    @Test
+    public void timeStringLength() {
+        int result = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = "hello, world!".length();
+        }
+    }
+
+    @Test
+    public void timeEmptyStatic() {
+        C c = new C();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            c.emptyStatic();
+        }
+    }
+
+    @Test
+    public void timeEmptyVirtual() {
+        C c = new C();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            c.emptyVirtual();
+        }
+    }
+
+    @Test
+    public void timeEmptyInterface() {
+        I c = new C();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            c.emptyInterface();
+        }
+    }
+
+    public static class Inner {
+        private int mI;
+
+        private void privateMethod() {
+            ++mI;
+        }
+
+        protected void protectedMethod() {
+            ++mI;
+        }
+
+        public void publicMethod() {
+            ++mI;
+        }
+
+        void packageMethod() {
+            ++mI;
+        }
+
+        final void finalPackageMethod() {
+            ++mI;
+        }
+    }
+
+    @Test
+    public void timePrivateInnerPublicMethod() {
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            inner.publicMethod();
+        }
+    }
+
+    @Test
+    public void timePrivateInnerProtectedMethod() {
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            inner.protectedMethod();
+        }
+    }
+
+    @Test
+    public void timePrivateInnerPrivateMethod() {
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            inner.privateMethod();
+        }
+    }
+
+    @Test
+    public void timePrivateInnerPackageMethod() {
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            inner.packageMethod();
+        }
+    }
+
+    @Test
+    public void timePrivateInnerFinalPackageMethod() {
+        Inner inner = new Inner();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            inner.finalPackageMethod();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java
new file mode 100644
index 0000000..8496fbe
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** How much do various kinds of multiplication cost? */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MultiplicationPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeMultiplyIntByConstant10() {
+        int result = 1;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result *= 10;
+        }
+    }
+
+    @Test
+    public void timeMultiplyIntByConstant8() {
+        int result = 1;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result *= 8;
+        }
+    }
+
+    @Test
+    public void timeMultiplyIntByVariable10() {
+        int result = 1;
+        int factor = 10;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result *= factor;
+        }
+    }
+
+    @Test
+    public void timeMultiplyIntByVariable8() {
+        int result = 1;
+        int factor = 8;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result *= factor;
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java
new file mode 100644
index 0000000..bb79424
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReferenceGetPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    boolean mIntrinsicDisabled;
+
+    private Object mObj = "str";
+
+    @Before
+    public void setUp() throws Exception {
+        Field intrinsicDisabledField = Reference.class.getDeclaredField("disableIntrinsic");
+        intrinsicDisabledField.setAccessible(true);
+        intrinsicDisabledField.setBoolean(null, mIntrinsicDisabled);
+    }
+
+    @Test
+    public void timeSoftReferenceGet() throws Exception {
+        Reference soft = new SoftReference(mObj);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Object o = soft.get();
+        }
+    }
+
+    @Test
+    public void timeWeakReferenceGet() throws Exception {
+        Reference weak = new WeakReference(mObj);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Object o = weak.get();
+        }
+    }
+
+    @Test
+    public void timeNonPreservedWeakReferenceGet() throws Exception {
+        Reference weak = new WeakReference(mObj);
+        mObj = null;
+        Runtime.getRuntime().gc();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Object o = weak.get();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java
new file mode 100644
index 0000000..2ef68ca
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** Benchmark to evaluate the performance of References. */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReferencePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private Object mObject;
+
+    // How fast can references can be allocated?
+    @Test
+    public void timeAlloc() {
+        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new PhantomReference(mObject, queue);
+        }
+    }
+
+    // How fast can references can be allocated and manually enqueued?
+    @Test
+    public void timeAllocAndEnqueue() {
+        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            (new PhantomReference<Object>(mObject, queue)).enqueue();
+        }
+    }
+
+    // How fast can references can be allocated, enqueued, and polled?
+    @Test
+    public void timeAllocEnqueueAndPoll() {
+        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            (new PhantomReference<Object>(mObject, queue)).enqueue();
+            queue.poll();
+        }
+    }
+
+    // How fast can references can be allocated, enqueued, and removed?
+    @Test
+    public void timeAllocEnqueueAndRemove() {
+        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            (new PhantomReference<Object>(mObject, queue)).enqueue();
+            try {
+                queue.remove();
+            } catch (InterruptedException ie) {
+            }
+        }
+    }
+
+    private static class FinalizableObject {
+        AtomicInteger mCount;
+
+        FinalizableObject(AtomicInteger count) {
+            this.mCount = count;
+        }
+
+        @Override
+        protected void finalize() {
+            mCount.incrementAndGet();
+        }
+    }
+
+    // How fast does finalization run?
+    @Test
+    public void timeFinalization() {
+        // Allocate a bunch of finalizable objects.
+        int n = 0;
+        AtomicInteger count = new AtomicInteger(0);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            n++;
+            new FinalizableObject(count);
+        }
+
+        // Run GC so the objects will be collected for finalization.
+        Runtime.getRuntime().gc();
+
+        // Wait for finalization.
+        Runtime.getRuntime().runFinalization();
+
+        // Double check all the objects were finalized.
+        int got = count.get();
+        if (n != got) {
+            throw new IllegalStateException(
+                    String.format("Only %i of %i objects finalized?", got, n));
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java
new file mode 100644
index 0000000..65a2fdb
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+/**
+ * This measures performance of operations on small BigIntegers. We manually determine the number of
+ * iterations so that it should cause total memory allocation on the order of a few hundred
+ * megabytes. Due to BigInteger's reliance on finalization, these may unfortunately all be kept
+ * around at once.
+ *
+ * <p>This is not structured as a proper benchmark; just run main(), e.g. with vogar
+ * libcore/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SmallBigIntegerPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    // We allocate about 2 1/3 BigIntegers per iteration.
+    // Assuming 100 bytes/BigInteger, this gives us around 500MB total.
+    static final BigInteger BIG_THREE = BigInteger.valueOf(3);
+    static final BigInteger BIG_FOUR = BigInteger.valueOf(4);
+
+    @Test
+    public void testSmallBigInteger() {
+        final Random r = new Random();
+        BigInteger x = new BigInteger(20, r);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // We know this converges, but the compiler doesn't.
+            if (x.and(BigInteger.ONE).equals(BigInteger.ONE)) {
+                x = x.multiply(BIG_THREE).add(BigInteger.ONE);
+            } else {
+                x = x.shiftRight(1);
+            }
+        }
+        if (x.signum() < 0 || x.compareTo(BIG_FOUR) > 0) {
+            throw new AssertionError("Something went horribly wrong.");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java
new file mode 100644
index 0000000..4f5c54d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** How long does it take to access a string in the dex cache? */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringDexCachePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeStringDexCacheAccess() {
+        int v = 0;
+        int count = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            // Deliberately obscured to make optimizations less likely.
+            String s = (count >= 0) ? "hello, world!" : null;
+            v += s.length();
+            ++count;
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java
new file mode 100644
index 0000000..08ad926
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** How do the various schemes for iterating through a string compare? */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringIterationPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeStringIteration0() {
+        String s = "hello, world!";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            char ch;
+            for (int i = 0; i < s.length(); ++i) {
+                ch = s.charAt(i);
+            }
+        }
+    }
+
+    @Test
+    public void timeStringIteration1() {
+        String s = "hello, world!";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            char ch;
+            for (int i = 0, length = s.length(); i < length; ++i) {
+                ch = s.charAt(i);
+            }
+        }
+    }
+
+    @Test
+    public void timeStringIteration2() {
+        String s = "hello, world!";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            char ch;
+            char[] chars = s.toCharArray();
+            for (int i = 0, length = chars.length; i < length; ++i) {
+                ch = chars[i];
+            }
+        }
+    }
+
+    @Test
+    public void timeStringToCharArray() {
+        String s = "hello, world!";
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            char[] chars = s.toCharArray();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java
new file mode 100644
index 0000000..5aacfc2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class SystemArrayCopyPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "arrayLength={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {2}, {4}, {8}, {16}, {32}, {64}, {128}, {256}, {512}, {1024}, {2048}, {4096},
+                    {8192}, {16384}, {32768}, {65536}, {131072}, {262144}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public int arrayLength;
+
+    // Provides benchmarking for different types of arrays using the arraycopy function.
+    @Test
+    public void timeSystemCharArrayCopy() {
+        final int len = arrayLength;
+        char[] src = new char[len];
+        char[] dst = new char[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemByteArrayCopy() {
+        final int len = arrayLength;
+        byte[] src = new byte[len];
+        byte[] dst = new byte[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemShortArrayCopy() {
+        final int len = arrayLength;
+        short[] src = new short[len];
+        short[] dst = new short[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemIntArrayCopy() {
+        final int len = arrayLength;
+        int[] src = new int[len];
+        int[] dst = new int[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemLongArrayCopy() {
+        final int len = arrayLength;
+        long[] src = new long[len];
+        long[] dst = new long[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemFloatArrayCopy() {
+        final int len = arrayLength;
+        float[] src = new float[len];
+        float[] dst = new float[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemDoubleArrayCopy() {
+        final int len = arrayLength;
+        double[] src = new double[len];
+        double[] dst = new double[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+
+    @Test
+    public void timeSystemBooleanArrayCopy() {
+        final int len = arrayLength;
+        boolean[] src = new boolean[len];
+        boolean[] dst = new boolean[len];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            System.arraycopy(src, 0, dst, 0, len);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java
new file mode 100644
index 0000000..7e71976
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Is there a performance reason to "Prefer virtual over interface", as the Android documentation
+ * once claimed?
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VirtualVersusInterfacePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeMapPut() {
+        Map<String, String> map = new HashMap<String, String>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.put("hello", "world");
+        }
+    }
+
+    @Test
+    public void timeHashMapPut() {
+        HashMap<String, String> map = new HashMap<String, String>();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            map.put("hello", "world");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java
new file mode 100644
index 0000000..eec0734
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.CharArrayWriter;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Random;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class XmlSerializePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mDatasetAsString({0}), mSeed({1})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {"0.99 0.7 0.7 0.7 0.7 0.7", 854328},
+                    {"0.999 0.3 0.3 0.95 0.9 0.9", 854328},
+                    {"0.99 0.7 0.7 0.7 0.7 0.7", 312547},
+                    {"0.999 0.3 0.3 0.95 0.9 0.9", 312547}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public String mDatasetAsString;
+
+    @Parameterized.Parameter(1)
+    public int mSeed;
+
+    double[] mDataset;
+    private Constructor<? extends XmlSerializer> mKxmlConstructor;
+    private Constructor<? extends XmlSerializer> mFastConstructor;
+
+    private void serializeRandomXml(Constructor<? extends XmlSerializer> ctor, long mSeed)
+            throws Exception {
+        double contChance = mDataset[0];
+        double levelUpChance = mDataset[1];
+        double levelDownChance = mDataset[2];
+        double attributeChance = mDataset[3];
+        double writeChance1 = mDataset[4];
+        double writeChance2 = mDataset[5];
+
+        XmlSerializer serializer = (XmlSerializer) ctor.newInstance();
+
+        CharArrayWriter w = new CharArrayWriter();
+        serializer.setOutput(w);
+        int level = 0;
+        Random r = new Random(mSeed);
+        char[] toWrite = {'a', 'b', 'c', 'd', 's', 'z'};
+        serializer.startDocument("UTF-8", true);
+        while (r.nextDouble() < contChance) {
+            while (level > 0 && r.nextDouble() < levelUpChance) {
+                serializer.endTag("aaaaaa", "bbbbbb");
+                level--;
+            }
+            while (r.nextDouble() < levelDownChance) {
+                serializer.startTag("aaaaaa", "bbbbbb");
+                level++;
+            }
+            serializer.startTag("aaaaaa", "bbbbbb");
+            level++;
+            while (r.nextDouble() < attributeChance) {
+                serializer.attribute("aaaaaa", "cccccc", "dddddd");
+            }
+            serializer.endTag("aaaaaa", "bbbbbb");
+            level--;
+            while (r.nextDouble() < writeChance1) serializer.text(toWrite, 0, 5);
+            while (r.nextDouble() < writeChance2) serializer.text("Textxtsxtxtxt ");
+        }
+        serializer.endDocument();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        mKxmlConstructor =
+                (Constructor)
+                        Class.forName("com.android.org.kxml2.io.KXmlSerializer").getConstructor();
+        mFastConstructor =
+                (Constructor)
+                        Class.forName("com.android.internal.util.FastXmlSerializer")
+                                .getConstructor();
+        String[] splitStrings = mDatasetAsString.split(" ");
+        mDataset = new double[splitStrings.length];
+        for (int i = 0; i < splitStrings.length; i++) {
+            mDataset[i] = Double.parseDouble(splitStrings[i]);
+        }
+    }
+
+    private void internalTimeSerializer(Constructor<? extends XmlSerializer> ctor)
+            throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            serializeRandomXml(ctor, mSeed);
+        }
+    }
+
+    @Test
+    public void timeKxml() throws Exception {
+        internalTimeSerializer(mKxmlConstructor);
+    }
+
+    @Test
+    public void timeFast() throws Exception {
+        internalTimeSerializer(mFastConstructor);
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
new file mode 100644
index 0000000..31c92ba
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class ZipFilePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private File mFile;
+
+    @Parameters(name = "numEntries={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{128}, {1024}, {8192}});
+    }
+
+    @Parameterized.Parameter(0)
+    public int numEntries;
+
+    @Before
+    public void setUp() throws Exception {
+        mFile = File.createTempFile(getClass().getName(), ".zip");
+        mFile.deleteOnExit();
+        writeEntries(new ZipOutputStream(new FileOutputStream(mFile)), numEntries, 0);
+        ZipFile zipFile = new ZipFile(mFile);
+        for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
+            ZipEntry zipEntry = e.nextElement();
+        }
+        zipFile.close();
+    }
+
+    @Test
+    public void timeZipFileOpen() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ZipFile zf = new ZipFile(mFile);
+            state.pauseTiming();
+            zf.close();
+            state.resumeTiming();
+        }
+    }
+
+    /** Compresses the given number of files, each of the given size, into a .zip archive. */
+    protected void writeEntries(ZipOutputStream out, int entryCount, long entrySize)
+            throws IOException {
+        byte[] writeBuffer = new byte[8192];
+        Random random = new Random();
+        try {
+            for (int entry = 0; entry < entryCount; ++entry) {
+                ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
+                ze.setSize(entrySize);
+                out.putNextEntry(ze);
+
+                for (long i = 0; i < entrySize; i += writeBuffer.length) {
+                    random.nextBytes(writeBuffer);
+                    int byteCount = (int) Math.min(writeBuffer.length, entrySize - i);
+                    out.write(writeBuffer, 0, byteCount);
+                }
+
+                out.closeEntry();
+            }
+        } finally {
+            out.close();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java
new file mode 100644
index 0000000..faa9628
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class ZipFileReadPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "readBufferSize={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{1024}, {16384}, {65536}});
+    }
+
+    private File mFile;
+
+    @Parameterized.Parameter(0)
+    public int readBufferSize;
+
+    @Before
+    public void setUp() throws Exception {
+        mFile = File.createTempFile(getClass().getName(), ".zip");
+        writeEntries(new ZipOutputStream(new FileOutputStream(mFile)), 2, 1024 * 1024);
+        ZipFile zipFile = new ZipFile(mFile);
+        for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
+            ZipEntry zipEntry = e.nextElement();
+        }
+        zipFile.close();
+    }
+
+    /** Compresses the given number of files, each of the given size, into a .zip archive. */
+    protected void writeEntries(ZipOutputStream out, int entryCount, long entrySize)
+            throws IOException {
+        byte[] writeBuffer = new byte[8192];
+        Random random = new Random();
+        try {
+            for (int entry = 0; entry < entryCount; ++entry) {
+                ZipEntry ze = new ZipEntry(Integer.toHexString(entry));
+                ze.setSize(entrySize);
+                out.putNextEntry(ze);
+
+                for (long i = 0; i < entrySize; i += writeBuffer.length) {
+                    random.nextBytes(writeBuffer);
+                    int byteCount = (int) Math.min(writeBuffer.length, entrySize - i);
+                    out.write(writeBuffer, 0, byteCount);
+                }
+
+                out.closeEntry();
+            }
+        } finally {
+            out.close();
+        }
+    }
+
+    @Test
+    public void timeZipFileRead() throws Exception {
+        byte[] readBuffer = new byte[readBufferSize];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ZipFile zipFile = new ZipFile(mFile);
+            for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
+                ZipEntry zipEntry = e.nextElement();
+                InputStream is = zipFile.getInputStream(zipEntry);
+                while (true) {
+                    if (is.read(readBuffer, 0, readBuffer.length) < 0) {
+                        break;
+                    }
+                }
+            }
+            zipFile.close();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java
new file mode 100644
index 0000000..d38d519
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class AnnotatedElementPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private Class<?> mType;
+    private Field mField;
+    private Method mMethod;
+
+    @Before
+    public void setUp() throws Exception {
+        mType = Type.class;
+        mField = Type.class.getField("field");
+        mMethod = Type.class.getMethod("method", String.class);
+    }
+
+    // get annotations by member type and method
+
+    @Test
+    public void timeGetTypeAnnotations() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mType.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetFieldAnnotations() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetMethodAnnotations() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mMethod.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetParameterAnnotations() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mMethod.getParameterAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetTypeAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mType.getAnnotation(Marker.class);
+        }
+    }
+
+    @Test
+    public void timeGetFieldAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.getAnnotation(Marker.class);
+        }
+    }
+
+    @Test
+    public void timeGetMethodAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mMethod.getAnnotation(Marker.class);
+        }
+    }
+
+    @Test
+    public void timeIsTypeAnnotationPresent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mType.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    @Test
+    public void timeIsFieldAnnotationPresent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    @Test
+    public void timeIsMethodAnnotationPresent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mMethod.isAnnotationPresent(Marker.class);
+        }
+    }
+
+    // get annotations by result size
+
+    @Test
+    public void timeGetAllReturnsLargeAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasLargeAnnotation.class.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetAllReturnsSmallAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasSmallAnnotation.class.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetAllReturnsMarkerAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasMarkerAnnotation.class.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetAllReturnsNoAnnotation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasNoAnnotations.class.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetAllReturnsThreeAnnotations() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasThreeAnnotations.class.getAnnotations();
+        }
+    }
+
+    // get annotations with inheritance
+
+    @Test
+    public void timeGetAnnotationsOnSubclass() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ExtendsHasThreeAnnotations.class.getAnnotations();
+        }
+    }
+
+    @Test
+    public void timeGetDeclaredAnnotationsOnSubclass() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ExtendsHasThreeAnnotations.class.getDeclaredAnnotations();
+        }
+    }
+
+    // get annotations with enclosing / inner classes
+
+    @Test
+    public void timeGetDeclaredClasses() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            AnnotatedElementPerfTest.class.getDeclaredClasses();
+        }
+    }
+
+    @Test
+    public void timeGetDeclaringClass() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasSmallAnnotation.class.getDeclaringClass();
+        }
+    }
+
+    @Test
+    public void timeGetEnclosingClass() {
+        Object anonymousClass = new Object() {};
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            anonymousClass.getClass().getEnclosingClass();
+        }
+    }
+
+    @Test
+    public void timeGetEnclosingConstructor() {
+        Object anonymousClass = new Object() {};
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            anonymousClass.getClass().getEnclosingConstructor();
+        }
+    }
+
+    @Test
+    public void timeGetEnclosingMethod() {
+        Object anonymousClass = new Object() {};
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            anonymousClass.getClass().getEnclosingMethod();
+        }
+    }
+
+    @Test
+    public void timeGetModifiers() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasSmallAnnotation.class.getModifiers();
+        }
+    }
+
+    @Test
+    public void timeGetSimpleName() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasSmallAnnotation.class.getSimpleName();
+        }
+    }
+
+    @Test
+    public void timeIsAnonymousClass() {
+        Object anonymousClass = new Object() {};
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            anonymousClass.getClass().isAnonymousClass();
+        }
+    }
+
+    @Test
+    public void timeIsLocalClass() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            HasSmallAnnotation.class.isLocalClass();
+        }
+    }
+
+    // the annotated elements
+
+    @Marker
+    public class Type {
+        @Marker public String field;
+
+        @Marker
+        public void method(@Marker String parameter) {}
+    }
+
+    @Large(
+            a = "on class",
+            b = {"A", "B", "C"},
+            c = @Small(e = "E1", f = 1695938256, g = 7264081114510713000L),
+            d = {@Small(e = "E2", f = 1695938256, g = 7264081114510713000L)})
+    public class HasLargeAnnotation {}
+
+    @Small(e = "E1", f = 1695938256, g = 7264081114510713000L)
+    public class HasSmallAnnotation {}
+
+    @Marker
+    public class HasMarkerAnnotation {}
+
+    public class HasNoAnnotations {}
+
+    @Large(
+            a = "on class",
+            b = {"A", "B", "C"},
+            c = @Small(e = "E1", f = 1695938256, g = 7264081114510713000L),
+            d = {@Small(e = "E2", f = 1695938256, g = 7264081114510713000L)})
+    @Small(e = "E1", f = 1695938256, g = 7264081114510713000L)
+    @Marker
+    public class HasThreeAnnotations {}
+
+    public class ExtendsHasThreeAnnotations extends HasThreeAnnotations {}
+
+    // the annotations
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Marker {}
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Large {
+        String a() default "";
+
+        String[] b() default {};
+
+        Small c() default @Small;
+
+        Small[] d() default {};
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Small {
+        String e() default "";
+
+        int f() default 0;
+
+        long g() default 0L;
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java
new file mode 100644
index 0000000..cc56868
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigDecimal;
+import java.text.AttributedCharacterIterator;
+import java.text.Bidi;
+import java.text.DecimalFormat;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class BidiPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final AttributedCharacterIterator CHAR_ITER =
+            DecimalFormat.getInstance().formatToCharacterIterator(new BigDecimal(Math.PI));
+
+    @Test
+    public void time_createBidiFromIter() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi bidi = new Bidi(CHAR_ITER);
+        }
+    }
+
+    @Test
+    public void time_createBidiFromCharArray() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi bd =
+                    new Bidi(
+                            new char[] {'s', 's', 's'},
+                            0,
+                            new byte[] {(byte) 1, (byte) 2, (byte) 3},
+                            0,
+                            3,
+                            Bidi.DIRECTION_RIGHT_TO_LEFT);
+        }
+    }
+
+    @Test
+    public void time_createBidiFromString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi bidi = new Bidi("Hello", Bidi.DIRECTION_LEFT_TO_RIGHT);
+        }
+    }
+
+    @Test
+    public void time_reorderVisually() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi.reorderVisually(
+                    new byte[] {2, 1, 3, 0, 4}, 0, new String[] {"H", "e", "l", "l", "o"}, 0, 5);
+        }
+    }
+
+    @Test
+    public void time_hebrewBidi() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi bd =
+                    new Bidi(
+                            new char[] {'\u05D0', '\u05D0', '\u05D0'},
+                            0,
+                            new byte[] {(byte) -1, (byte) -2, (byte) -3},
+                            0,
+                            3,
+                            Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+            bd =
+                    new Bidi(
+                            new char[] {'\u05D0', '\u05D0', '\u05D0'},
+                            0,
+                            new byte[] {(byte) -1, (byte) -2, (byte) -3},
+                            0,
+                            3,
+                            Bidi.DIRECTION_LEFT_TO_RIGHT);
+        }
+    }
+
+    @Test
+    public void time_complicatedOverrideBidi() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi bd =
+                    new Bidi(
+                            "a\u05D0a\"a\u05D0\"\u05D0a".toCharArray(),
+                            0,
+                            new byte[] {0, 0, 0, -3, -3, 2, 2, 0, 3},
+                            0,
+                            9,
+                            Bidi.DIRECTION_RIGHT_TO_LEFT);
+        }
+    }
+
+    @Test
+    public void time_requiresBidi() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bidi.requiresBidi("\u05D0".toCharArray(), 1, 1); // false.
+            Bidi.requiresBidi("\u05D0".toCharArray(), 0, 1); // true.
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java
new file mode 100644
index 0000000..662694b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class BigIntegerPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeRandomDivision() throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x.divide(y);
+        }
+    }
+
+    @Test
+    public void timeRandomGcd() throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x.gcd(y);
+        }
+    }
+
+    @Test
+    public void timeRandomMultiplication() throws Exception {
+        Random r = new Random();
+        BigInteger x = new BigInteger(1024, r);
+        BigInteger y = new BigInteger(1024, r);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x.multiply(y);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java
new file mode 100644
index 0000000..db5462c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class BitSetPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mSize={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{1000}, {10000}});
+    }
+
+    @Parameterized.Parameter(0)
+    public int mSize;
+
+    private BitSet mBitSet;
+
+    @Before
+    public void setUp() throws Exception {
+        mBitSet = new BitSet(mSize);
+    }
+
+    @Test
+    public void timeIsEmptyTrue() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            if (!mBitSet.isEmpty()) throw new RuntimeException();
+        }
+    }
+
+    @Test
+    public void timeIsEmptyFalse() {
+        mBitSet.set(mBitSet.size() - 1);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            if (mBitSet.isEmpty()) throw new RuntimeException();
+        }
+    }
+
+    @Test
+    public void timeGet() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        int i = 1;
+        while (state.keepRunning()) {
+            mBitSet.get(++i % mSize);
+        }
+    }
+
+    @Test
+    public void timeClear() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        int i = 1;
+        while (state.keepRunning()) {
+            mBitSet.clear(++i % mSize);
+        }
+    }
+
+    @Test
+    public void timeSet() {
+        int i = 1;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mBitSet.set(++i % mSize);
+        }
+    }
+
+    @Test
+    public void timeSetOn() {
+        int i = 1;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mBitSet.set(++i % mSize, true);
+        }
+    }
+
+    @Test
+    public void timeSetOff() {
+        int i = 1;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mBitSet.set(++i % mSize, false);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java
new file mode 100644
index 0000000..3952c12
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.text.BreakIterator;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Locale;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public final class BreakIteratorPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    public enum Text {
+        LIPSUM(
+                Locale.US,
+                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mollis consequat"
+                    + " nisl non pharetra. Praesent pretium vehicula odio sed ultrices. Aenean a"
+                    + " felis libero. Vivamus sed commodo nibh. Pellentesque turpis lectus, euismod"
+                    + " vel ante nec, cursus posuere orci. Suspendisse velit neque, fermentum"
+                    + " luctus ultrices in, ultrices vitae arcu. Duis tincidunt cursus lorem. Nam"
+                    + " ultricies accumsan quam vitae imperdiet. Pellentesque habitant morbi"
+                    + " tristique senectus et netus et malesuada fames ac turpis egestas. Quisque"
+                    + " aliquet pretium nisi, eget laoreet enim molestie sit amet. Class aptent"
+                    + " taciti sociosqu ad litora torquent per conubia nostra, per inceptos"
+                    + " himenaeos.\n"
+                    + "Nam dapibus aliquam lacus ac suscipit. Proin in nibh sit amet purus congue"
+                    + " laoreet eget quis nisl. Morbi gravida dignissim justo, a venenatis ante"
+                    + " pulvinar at. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin"
+                    + " ultrices vestibulum dui, vel aliquam lacus aliquam quis. Duis fringilla"
+                    + " sapien ac lacus egestas, vel adipiscing elit euismod. Donec non tellus"
+                    + " odio. Donec gravida eu massa ac feugiat. Aliquam erat volutpat. Praesent id"
+                    + " adipiscing metus, nec laoreet enim. Aliquam vitae posuere turpis. Mauris ac"
+                    + " pharetra sem. In at placerat tortor. Vivamus ac vehicula neque. Cras"
+                    + " volutpat ullamcorper massa et varius. Praesent sagittis neque vitae nulla"
+                    + " euismod pharetra.\n"
+                    + "Sed placerat sapien non molestie sollicitudin. Nullam sit amet dictum quam."
+                    + " Etiam tincidunt tortor vel pretium vehicula. Praesent fringilla ipsum vel"
+                    + " velit luctus dignissim. Nulla massa ligula, mattis in enim et, mattis"
+                    + " lacinia odio. Suspendisse tristique urna a orci commodo tempor. Duis"
+                    + " lacinia egestas arcu a sollicitudin.\n"
+                    + "In ac feugiat lacus. Nunc fermentum eu est at tristique. Pellentesque quis"
+                    + " ligula et orci placerat lacinia. Maecenas quis mauris diam. Etiam mi ipsum,"
+                    + " tempus in purus quis, euismod faucibus orci. Nulla facilisi. Praesent sit"
+                    + " amet sapien vel elit porta adipiscing. Phasellus sit amet volutpat diam.\n"
+                    + "Proin bibendum elit non lacus pharetra, quis eleifend tellus placerat. Nulla"
+                    + " facilisi. Maecenas ante diam, pellentesque mattis mattis in, porta ut"
+                    + " lorem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices"
+                    + " posuere cubilia Curae; Nunc interdum tristique metus, in scelerisque odio"
+                    + " fermentum eget. Cras nec venenatis lacus. Aenean euismod eget metus quis"
+                    + " molestie. Cras tincidunt dolor ut massa ornare, in elementum lacus auctor."
+                    + " Cras sodales nisl lacus, id ultrices ligula varius at. Sed tristique sit"
+                    + " amet tellus vel mollis. Sed sed sollicitudin quam. Sed sed adipiscing"
+                    + " risus, et dictum orci. Cras tempor pellentesque turpis et tempus."),
+        LONGPARA(
+                Locale.US,
+                "During dinner, Mr. Bennet scarcely spoke at all; but when the servants were"
+                    + " withdrawn, he thought it time to have some conversation with his guest, and"
+                    + " therefore started a subject in which he expected him to shine, by observing"
+                    + " that he seemed very fortunate in his patroness. Lady Catherine de Bourgh's"
+                    + " attention to his wishes, and consideration for his comfort, appeared very"
+                    + " remarkable. Mr. Bennet could not have chosen better. Mr. Collins was"
+                    + " eloquent in her praise. The subject elevated him to more than usual"
+                    + " solemnity of manner, and with a most important aspect he protested that"
+                    + " \"he had never in his life witnessed such behaviour in a person of"
+                    + " rank--such affability and condescension, as he had himself experienced from"
+                    + " Lady Catherine. She had been graciously pleased to approve of both of the"
+                    + " discourses which he had already had the honour of preaching before her. She"
+                    + " had also asked him twice to dine at Rosings, and had sent for him only the"
+                    + " Saturday before, to make up her pool of quadrille in the evening. Lady"
+                    + " Catherine was reckoned proud by many people he knew, but _he_ had never"
+                    + " seen anything but affability in her. She had always spoken to him as she"
+                    + " would to any other gentleman; she made not the smallest objection to his"
+                    + " joining in the society of the neighbourhood nor to his leaving the parish"
+                    + " occasionally for a week or two, to visit his relations. She had even"
+                    + " condescended to advise him to marry as soon as he could, provided he chose"
+                    + " with discretion; and had once paid him a visit in his humble parsonage,"
+                    + " where she had perfectly approved all the alterations he had been making,"
+                    + " and had even vouchsafed to suggest some herself--some shelves in the closet"
+                    + " up stairs.\""),
+        GERMAN(
+                Locale.GERMANY,
+                "Aber dieser Freiheit setzte endlich der Winter ein Ziel. Draußen auf den Feldern"
+                    + " und den hohen Bergen lag der Schnee und Peter wäre in seinem dünnen"
+                    + " Leinwandjäckchen bald erfroren. Es war also seine einzige Freude, hinaus"
+                    + " vor die Hütte zu treten und den Sperlingen Brotkrümchen zu streuen, was er"
+                    + " sich jedesmal an seinem Frühstück absparte. Wenn nun die Vögel so lustig"
+                    + " zwitscherten und um ihn herumflogen, da klopfte ihm das Herz vor Lust, und"
+                    + " oft gab er ihnen sein ganzes Stück Schwarzbrot, ohne daran zu denken, daß"
+                    + " er dafür alsdann selbst hungern müsse."),
+        THAI(
+                Locale.forLanguageTag("th-TH"),
+                "เป็นสำเนียงทางการของภาษาไทย"
+                    + " เดิมทีเป็นการผสมผสานกันระหว่างสำเนียงอยุธยาและชาวไทยเชื้อสายจีนรุ่นหลังที่"
+                    + "พูดไทยแทนกลุ่มภาษาจีน"
+                    + " ลักษณะเด่นคือมีการออกเสียงที่ชัดเจนและแข็งกระด้างซึ่งได้รับอิทธิพลจากภาษาแต"
+                    + "้จิ๋ว"
+                    + " การออกเสียงพยัญชนะ สระ การผันวรรณยุกต์ที่ในภาษาไทยมาตรฐาน"
+                    + " มาจากสำเนียงถิ่นนี้ในขณะที่ภาษาไทยสำเนียงอื่นล้วนเหน่อทั้งสิ้น"
+                    + " คำศัพท์ที่ใช้ในสำเนียงกรุงเทพจำนวนมากได้รับมาจากกลุ่มภาษาจีนเช่นคำว่า โป๊,"
+                    + " เฮ็ง, อาหมวย, อาซิ่ม ซึ่งมาจากภาษาแต้จิ๋ว และจากภาษาจีนเช่น ถู(涂), ชิ่ว(去"
+                    + " อ่านว่า\"ชู่\") และคำว่า ทาย(猜 อ่านว่า \"ชาย\") เป็นต้น"
+                    + " เนื่องจากสำเนียงกรุงเทพได้รับอิทธิพลมาจากภาษาจีนดังนั้นตัวอักษร \"ร\""
+                    + " มักออกเสียงเหมารวมเป็น \"ล\" หรือคำควบกล่ำบางคำถูกละทิ้งไปด้วยเช่น รู้ เป็น"
+                    + " ลู้, เรื่อง เป็น เลื่อง หรือ ประเทศ เป็น ปะเทศ"
+                    + " เป็นต้นสร้างความลำบากให้แก่ต่างชาติที่ต้องการเรียนภาษาไทย"
+                    + " แต่อย่างไรก็ตามผู้ที่พูดสำเนียงถิ่นนี้ก็สามารถออกอักขระภาษาไทยตามมาตรฐานได"
+                    + "้อย่างถูกต้องเพียงแต่มักเผลอไม่ค่อยออกเสียง"),
+        THAI2(Locale.forLanguageTag("th-TH"), "this is the word browser in Thai: เบราว์เซอร์"),
+        TABS(Locale.US, "one\t\t\t\t\t\t\t\t\t\t\t\t\t\ttwo\n"),
+        ACCENT(Locale.US, "e\u0301\u00e9\nwhich is:\n\"e\\u0301\\u00e9\""),
+        EMOJI(Locale.US, ">>\ud83d\ude01<<\nwhich is:\n\">>\\ud83d\\ude01<<\""),
+        SPACES(Locale.US, "     leading spaces      and trailing ones too      "),
+        EMPTY(Locale.US, ""),
+        NEWLINE(Locale.US, "\\n:\n"),
+        BIDI(
+                Locale.forLanguageTag("he-IL"),
+                "Sarah שרה is spelled sin ש resh ר heh ה from right to left.");
+
+        final Locale mLocale;
+        final String mText;
+
+        Text(Locale locale, String text) {
+            this.mText = text;
+            this.mLocale = locale;
+        }
+    }
+
+    @Parameters(name = "mText={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {Text.ACCENT}, {Text.BIDI}, {Text.EMOJI}, {Text.EMPTY}, {Text.GERMAN},
+                    {Text.LIPSUM}, {Text.LONGPARA}, {Text.NEWLINE}, {Text.SPACES}, {Text.TABS},
+                    {Text.THAI}, {Text.THAI2}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public Text mText;
+
+    @Test
+    public void timeBreakIterator() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            BreakIterator it = BreakIterator.getLineInstance(mText.mLocale);
+            it.setText(mText.mText);
+
+            while (it.next() != BreakIterator.DONE) {
+                // Keep iterating
+            }
+        }
+    }
+
+    @Test
+    public void timeIcuBreakIterator() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            android.icu.text.BreakIterator it =
+                    android.icu.text.BreakIterator.getLineInstance(mText.mLocale);
+            it.setText(mText.mText);
+
+            while (it.next() != android.icu.text.BreakIterator.DONE) {
+                // Keep iterating
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferBulkPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferBulkPerfTest.java
new file mode 100644
index 0000000..8e57b28
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferBulkPerfTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class ByteBufferBulkPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mAligned({0}), mSrcBufferType({1}), mDataBufferType({2}), mBufferSize({3})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {true, MyBufferType.DIRECT, MyBufferType.DIRECT, 4096},
+                    {false, MyBufferType.DIRECT, MyBufferType.DIRECT, 4096},
+                    {true, MyBufferType.HEAP, MyBufferType.DIRECT, 4096},
+                    {false, MyBufferType.HEAP, MyBufferType.DIRECT, 4096},
+                    {true, MyBufferType.MAPPED, MyBufferType.DIRECT, 4096},
+                    {false, MyBufferType.MAPPED, MyBufferType.DIRECT, 4096},
+                    {true, MyBufferType.DIRECT, MyBufferType.HEAP, 4096},
+                    {false, MyBufferType.DIRECT, MyBufferType.HEAP, 4096},
+                    {true, MyBufferType.HEAP, MyBufferType.HEAP, 4096},
+                    {false, MyBufferType.HEAP, MyBufferType.HEAP, 4096},
+                    {true, MyBufferType.MAPPED, MyBufferType.HEAP, 4096},
+                    {false, MyBufferType.MAPPED, MyBufferType.HEAP, 4096},
+                    {true, MyBufferType.DIRECT, MyBufferType.MAPPED, 4096},
+                    {false, MyBufferType.DIRECT, MyBufferType.MAPPED, 4096},
+                    {true, MyBufferType.HEAP, MyBufferType.MAPPED, 4096},
+                    {false, MyBufferType.HEAP, MyBufferType.MAPPED, 4096},
+                    {true, MyBufferType.MAPPED, MyBufferType.MAPPED, 4096},
+                    {false, MyBufferType.MAPPED, MyBufferType.MAPPED, 4096},
+                    {true, MyBufferType.DIRECT, MyBufferType.DIRECT, 1232896},
+                    {false, MyBufferType.DIRECT, MyBufferType.DIRECT, 1232896},
+                    {true, MyBufferType.HEAP, MyBufferType.DIRECT, 1232896},
+                    {false, MyBufferType.HEAP, MyBufferType.DIRECT, 1232896},
+                    {true, MyBufferType.MAPPED, MyBufferType.DIRECT, 1232896},
+                    {false, MyBufferType.MAPPED, MyBufferType.DIRECT, 1232896},
+                    {true, MyBufferType.DIRECT, MyBufferType.HEAP, 1232896},
+                    {false, MyBufferType.DIRECT, MyBufferType.HEAP, 1232896},
+                    {true, MyBufferType.HEAP, MyBufferType.HEAP, 1232896},
+                    {false, MyBufferType.HEAP, MyBufferType.HEAP, 1232896},
+                    {true, MyBufferType.MAPPED, MyBufferType.HEAP, 1232896},
+                    {false, MyBufferType.MAPPED, MyBufferType.HEAP, 1232896},
+                    {true, MyBufferType.DIRECT, MyBufferType.MAPPED, 1232896},
+                    {false, MyBufferType.DIRECT, MyBufferType.MAPPED, 1232896},
+                    {true, MyBufferType.HEAP, MyBufferType.MAPPED, 1232896},
+                    {false, MyBufferType.HEAP, MyBufferType.MAPPED, 1232896},
+                    {true, MyBufferType.MAPPED, MyBufferType.MAPPED, 1232896},
+                    {false, MyBufferType.MAPPED, MyBufferType.MAPPED, 1232896},
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public boolean mAligned;
+
+    enum MyBufferType {
+        DIRECT,
+        HEAP,
+        MAPPED
+    }
+
+    @Parameterized.Parameter(1)
+    public MyBufferType mSrcBufferType;
+
+    @Parameterized.Parameter(2)
+    public MyBufferType mDataBufferType;
+
+    @Parameterized.Parameter(3)
+    public int mBufferSize;
+
+    public static ByteBuffer newBuffer(boolean aligned, MyBufferType bufferType, int bsize)
+            throws IOException {
+        int size = aligned ? bsize : bsize + 8 + 1;
+        ByteBuffer result = null;
+        switch (bufferType) {
+            case DIRECT:
+                result = ByteBuffer.allocateDirect(size);
+                break;
+            case HEAP:
+                result = ByteBuffer.allocate(size);
+                break;
+            case MAPPED:
+                File tmpFile = File.createTempFile("MappedByteBufferTest", ".tmp");
+                tmpFile.createNewFile();
+                tmpFile.deleteOnExit();
+                RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
+                raf.setLength(size);
+                FileChannel fc = raf.getChannel();
+                result = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
+                break;
+        }
+        result.position(aligned ? 0 : 1);
+        return result;
+    }
+
+    @Test
+    public void timeByteBuffer_putByteBuffer() throws Exception {
+        ByteBuffer src = ByteBufferBulkPerfTest.newBuffer(mAligned, mSrcBufferType, mBufferSize);
+        ByteBuffer data = ByteBufferBulkPerfTest.newBuffer(mAligned, mDataBufferType, mBufferSize);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            data.position(mAligned ? 0 : 1);
+            src.put(data);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java
new file mode 100644
index 0000000..4bd7c4e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class ByteBufferPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    public enum MyByteOrder {
+        BIG(ByteOrder.BIG_ENDIAN),
+        LITTLE(ByteOrder.LITTLE_ENDIAN);
+        final ByteOrder mByteOrder;
+
+        MyByteOrder(ByteOrder mByteOrder) {
+            this.mByteOrder = mByteOrder;
+        }
+    }
+
+    @Parameters(name = "mByteOrder={0}, mAligned={1}, mBufferType={2}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {MyByteOrder.BIG, true, MyBufferType.DIRECT},
+                    {MyByteOrder.LITTLE, true, MyBufferType.DIRECT},
+                    {MyByteOrder.BIG, false, MyBufferType.DIRECT},
+                    {MyByteOrder.LITTLE, false, MyBufferType.DIRECT},
+                    {MyByteOrder.BIG, true, MyBufferType.HEAP},
+                    {MyByteOrder.LITTLE, true, MyBufferType.HEAP},
+                    {MyByteOrder.BIG, false, MyBufferType.HEAP},
+                    {MyByteOrder.LITTLE, false, MyBufferType.HEAP},
+                    {MyByteOrder.BIG, true, MyBufferType.MAPPED},
+                    {MyByteOrder.LITTLE, true, MyBufferType.MAPPED},
+                    {MyByteOrder.BIG, false, MyBufferType.MAPPED},
+                    {MyByteOrder.LITTLE, false, MyBufferType.MAPPED}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public MyByteOrder mByteOrder;
+
+    @Parameterized.Parameter(1)
+    public boolean mAligned;
+
+    enum MyBufferType {
+        DIRECT,
+        HEAP,
+        MAPPED;
+    }
+
+    @Parameterized.Parameter(2)
+    public MyBufferType mBufferType;
+
+    public static ByteBuffer newBuffer(
+            MyByteOrder byteOrder, boolean aligned, MyBufferType bufferType) throws IOException {
+        int size = aligned ? 8192 : 8192 + 8 + 1;
+        ByteBuffer result = null;
+        switch (bufferType) {
+            case DIRECT:
+                result = ByteBuffer.allocateDirect(size);
+                break;
+            case HEAP:
+                result = ByteBuffer.allocate(size);
+                break;
+            case MAPPED:
+                File tmpFile = new File("/sdcard/bm.tmp");
+                if (new File("/tmp").isDirectory()) {
+                    // We're running on the desktop.
+                    tmpFile = File.createTempFile("MappedByteBufferTest", ".tmp");
+                }
+                tmpFile.createNewFile();
+                tmpFile.deleteOnExit();
+                RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
+                raf.setLength(8192 * 8);
+                FileChannel fc = raf.getChannel();
+                result = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size());
+                break;
+        }
+        result.order(byteOrder.mByteOrder);
+        result.position(aligned ? 0 : 1);
+        return result;
+    }
+
+    //
+    // peeking
+    //
+
+    @Test
+    public void timeByteBuffer_getByte() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.get();
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getByteArray() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        byte[] dst = new byte[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(mAligned ? 0 : 1);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getByte_indexed() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.get(i);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getChar() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getChar();
+            }
+        }
+    }
+
+    @Test
+    public void timeCharBuffer_getCharArray() throws Exception {
+        CharBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asCharBuffer();
+        char[] dst = new char[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getChar_indexed() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getChar(i * 2);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getDouble() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getDouble();
+            }
+        }
+    }
+
+    @Test
+    public void timeDoubleBuffer_getDoubleArray() throws Exception {
+        DoubleBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asDoubleBuffer();
+        double[] dst = new double[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getFloat() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getFloat();
+            }
+        }
+    }
+
+    @Test
+    public void timeFloatBuffer_getFloatArray() throws Exception {
+        FloatBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asFloatBuffer();
+        float[] dst = new float[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getInt() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getInt();
+            }
+        }
+    }
+
+    @Test
+    public void timeIntBuffer_getIntArray() throws Exception {
+        IntBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asIntBuffer();
+        int[] dst = new int[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getLong() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getLong();
+            }
+        }
+    }
+
+    @Test
+    public void timeLongBuffer_getLongArray() throws Exception {
+        LongBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asLongBuffer();
+        long[] dst = new long[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_getShort() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.getShort();
+            }
+        }
+    }
+
+    @Test
+    public void timeShortBuffer_getShortArray() throws Exception {
+        ShortBuffer src =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asShortBuffer();
+        short[] dst = new short[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                src.position(0);
+                src.get(dst);
+            }
+        }
+    }
+
+    //
+    // poking
+    //
+
+    @Test
+    public void timeByteBuffer_putByte() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(0);
+            for (int i = 0; i < 1024; ++i) {
+                src.put((byte) 0);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putByteArray() throws Exception {
+        ByteBuffer dst = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        byte[] src = new byte[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(mAligned ? 0 : 1);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putChar() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putChar(' ');
+            }
+        }
+    }
+
+    @Test
+    public void timeCharBuffer_putCharArray() throws Exception {
+        CharBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asCharBuffer();
+        char[] src = new char[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putDouble() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putDouble(0.0);
+            }
+        }
+    }
+
+    @Test
+    public void timeDoubleBuffer_putDoubleArray() throws Exception {
+        DoubleBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asDoubleBuffer();
+        double[] src = new double[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putFloat() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putFloat(0.0f);
+            }
+        }
+    }
+
+    @Test
+    public void timeFloatBuffer_putFloatArray() throws Exception {
+        FloatBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asFloatBuffer();
+        float[] src = new float[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putInt() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putInt(0);
+            }
+        }
+    }
+
+    @Test
+    public void timeIntBuffer_putIntArray() throws Exception {
+        IntBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asIntBuffer();
+        int[] src = new int[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putLong() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putLong(0L);
+            }
+        }
+    }
+
+    @Test
+    public void timeLongBuffer_putLongArray() throws Exception {
+        LongBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asLongBuffer();
+        long[] src = new long[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBuffer_putShort() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            for (int i = 0; i < 1024; ++i) {
+                src.putShort((short) 0);
+            }
+        }
+    }
+
+    @Test
+    public void timeShortBuffer_putShortArray() throws Exception {
+        ShortBuffer dst =
+                ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType).asShortBuffer();
+        short[] src = new short[1024];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < 1024; ++i) {
+                dst.position(0);
+                dst.put(src);
+            }
+        }
+    }
+
+    @Test
+    public void time_new_byteArray() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            byte[] bs = new byte[8192];
+        }
+    }
+
+    @Test
+    public void time_ByteBuffer_allocate() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ByteBuffer bs = ByteBuffer.allocate(8192);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java
new file mode 100644
index 0000000..81f9e59
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class ByteBufferScalarVersusVectorPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mByteOrder={0}, mAligned={1}, mBufferType={2}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.DIRECT
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.DIRECT
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.DIRECT
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.DIRECT
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.HEAP
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.HEAP
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.HEAP
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.HEAP
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.MAPPED
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        true,
+                        ByteBufferPerfTest.MyBufferType.MAPPED
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.BIG,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.MAPPED
+                    },
+                    {
+                        ByteBufferPerfTest.MyByteOrder.LITTLE,
+                        false,
+                        ByteBufferPerfTest.MyBufferType.MAPPED
+                    }
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public ByteBufferPerfTest.MyByteOrder mByteOrder;
+
+    @Parameterized.Parameter(1)
+    public boolean mAligned;
+
+    @Parameterized.Parameter(2)
+    public ByteBufferPerfTest.MyBufferType mBufferType;
+
+    @Test
+    public void timeManualByteBufferCopy() throws Exception {
+        ByteBuffer src = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        ByteBuffer dst = ByteBufferPerfTest.newBuffer(mByteOrder, mAligned, mBufferType);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(0);
+            dst.position(0);
+            for (int i = 0; i < 8192; ++i) {
+                dst.put(src.get());
+            }
+        }
+    }
+
+    @Test
+    public void timeByteBufferBulkGet() throws Exception {
+        ByteBuffer src = ByteBuffer.allocate(mAligned ? 8192 : 8192 + 1);
+        byte[] dst = new byte[8192];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            src.get(dst, 0, dst.length);
+        }
+    }
+
+    @Test
+    public void timeDirectByteBufferBulkGet() throws Exception {
+        ByteBuffer src = ByteBuffer.allocateDirect(mAligned ? 8192 : 8192 + 1);
+        byte[] dst = new byte[8192];
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            src.position(mAligned ? 0 : 1);
+            src.get(dst, 0, dst.length);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java
new file mode 100644
index 0000000..28ec6de
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Tests various Character methods, intended for testing multiple implementations against each
+ * other.
+ */
+@RunWith(Parameterized.class)
+@LargeTest
+public class CharacterPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mCharacterSet({0}), mOverload({1})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {CharacterSet.ASCII, Overload.CHAR},
+                    {CharacterSet.ASCII, Overload.INT},
+                    {CharacterSet.UNICODE, Overload.CHAR},
+                    {CharacterSet.UNICODE, Overload.INT}
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public CharacterSet mCharacterSet;
+
+    @Parameterized.Parameter(1)
+    public Overload mOverload;
+
+    private char[] mChars;
+
+    @Before
+    public void setUp() throws Exception {
+        this.mChars = mCharacterSet.mChars;
+    }
+
+    public enum Overload {
+        CHAR,
+        INT
+    }
+
+    public double nanosToUnits(double nanos) {
+        return nanos / 65536;
+    }
+
+    public enum CharacterSet {
+        ASCII(128),
+        UNICODE(65536);
+        final char[] mChars;
+
+        CharacterSet(int size) {
+            this.mChars = new char[65536];
+            for (int i = 0; i < 65536; ++i) {
+                mChars[i] = (char) (i % size);
+            }
+        }
+    }
+
+    // A fake benchmark to give us a baseline.
+    @Test
+    public void timeIsSpace() {
+        boolean fake = false;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    fake ^= ((char) ch == ' ');
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    fake ^= (ch == ' ');
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeDigit() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.digit(mChars[ch], 10);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.digit((int) mChars[ch], 10);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeGetNumericValue() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.getNumericValue(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.getNumericValue((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsDigit() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isDigit(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isDigit((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsIdentifierIgnorable() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isIdentifierIgnorable(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isIdentifierIgnorable((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsJavaIdentifierPart() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isJavaIdentifierPart(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isJavaIdentifierPart((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsJavaIdentifierStart() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isJavaIdentifierStart(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isJavaIdentifierStart((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsLetter() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLetter(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLetter((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsLetterOrDigit() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLetterOrDigit(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLetterOrDigit((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsLowerCase() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLowerCase(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isLowerCase((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsSpaceChar() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isSpaceChar(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isSpaceChar((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsUpperCase() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isUpperCase(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isUpperCase((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeIsWhitespace() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isWhitespace(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.isWhitespace((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeToLowerCase() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.toLowerCase(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.toLowerCase((int) mChars[ch]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void timeToUpperCase() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        if (mOverload == Overload.CHAR) {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.toUpperCase(mChars[ch]);
+                }
+            }
+        } else {
+            while (state.keepRunning()) {
+                for (int ch = 0; ch < 65536; ++ch) {
+                    Character.toUpperCase((int) mChars[ch]);
+                }
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java
new file mode 100644
index 0000000..603b182
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class CharsetForNamePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameterized.Parameters(name = "mCharsetName({0})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {"UTF-16"},
+                    {"UTF-8"},
+                    {"UTF8"},
+                    {"ISO-8859-1"},
+                    {"8859_1"},
+                    {"ISO-8859-2"},
+                    {"8859_2"},
+                    {"US-ASCII"},
+                    {"ASCII"},
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public String mCharsetName;
+
+    @Test
+    public void timeCharsetForName() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Charset.forName(mCharsetName);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java
new file mode 100644
index 0000000..437d186
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class CharsetPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mLength({0}), mName({1})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(
+                new Object[][] {
+                    {1, "UTF-16"},
+                    {1, "UTF-8"},
+                    {1, "UTF8"},
+                    {1, "ISO-8859-1"},
+                    {1, "8859_1"},
+                    {1, "ISO-8859-2"},
+                    {1, "8859_2"},
+                    {1, "US-ASCII"},
+                    {1, "ASCII"},
+                    {10, "UTF-16"},
+                    {10, "UTF-8"},
+                    {10, "UTF8"},
+                    {10, "ISO-8859-1"},
+                    {10, "8859_1"},
+                    {10, "ISO-8859-2"},
+                    {10, "8859_2"},
+                    {10, "US-ASCII"},
+                    {10, "ASCII"},
+                    {100, "UTF-16"},
+                    {100, "UTF-8"},
+                    {100, "UTF8"},
+                    {100, "ISO-8859-1"},
+                    {100, "8859_1"},
+                    {100, "ISO-8859-2"},
+                    {100, "8859_2"},
+                    {100, "US-ASCII"},
+                    {100, "ASCII"},
+                    {1000, "UTF-16"},
+                    {1000, "UTF-8"},
+                    {1000, "UTF8"},
+                    {1000, "ISO-8859-1"},
+                    {1000, "8859_1"},
+                    {1000, "ISO-8859-2"},
+                    {1000, "8859_2"},
+                    {1000, "US-ASCII"},
+                    {1000, "ASCII"},
+                    {10000, "UTF-16"},
+                    {10000, "UTF-8"},
+                    {10000, "UTF8"},
+                    {10000, "ISO-8859-1"},
+                    {10000, "8859_1"},
+                    {10000, "ISO-8859-2"},
+                    {10000, "8859_2"},
+                    {10000, "US-ASCII"},
+                    {10000, "ASCII"},
+                });
+    }
+
+    @Parameterized.Parameter(0)
+    public int mLength;
+
+    @Parameterized.Parameter(1)
+    public String mName;
+
+    @Test
+    public void time_new_String_BString() throws Exception {
+        byte[] bytes = makeBytes(makeString(mLength));
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new String(bytes, mName);
+        }
+    }
+
+    @Test
+    public void time_new_String_BII() throws Exception {
+        byte[] bytes = makeBytes(makeString(mLength));
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new String(bytes, 0, bytes.length);
+        }
+    }
+
+    @Test
+    public void time_new_String_BIIString() throws Exception {
+        byte[] bytes = makeBytes(makeString(mLength));
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new String(bytes, 0, bytes.length, mName);
+        }
+    }
+
+    @Test
+    public void time_String_getBytes() throws Exception {
+        String string = makeString(mLength);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            string.getBytes(mName);
+        }
+    }
+
+    private static String makeString(int length) {
+        StringBuilder result = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            result.append('A' + (i % 26));
+        }
+        return result.toString();
+    }
+
+    private static byte[] makeBytes(String s) {
+        try {
+            return s.getBytes("US-ASCII");
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
new file mode 100644
index 0000000..f31e9c1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.libcore.regression;
+
+import android.icu.lang.UCharacter;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.charset.Charset;
+
+/**
+ * Decode the same size of ASCII, BMP, Supplementary character using fast-path UTF-8 decoder. The
+ * fast-path code is in {@link StringFactory#newStringFromBytes(byte[], int, int, Charset)}
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CharsetUtf8PerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private final int mNoOfBytes = 0x100; // 4MB
+
+    private void makeUnicodeRange(int startingCodePoint, int endingCodePoint, int repeated) {
+        StringBuilder builder = new StringBuilder();
+        for (int codePoint = startingCodePoint; codePoint <= endingCodePoint; codePoint++) {
+            if (codePoint < Character.MIN_SURROGATE || codePoint > Character.MAX_SURROGATE) {
+                builder.append(UCharacter.toString(codePoint));
+            }
+        }
+
+        String str = builder.toString();
+        StringBuilder builder2 = new StringBuilder();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < repeated; i++) {
+                builder2.append(str);
+            }
+        }
+    }
+
+    @Test
+    public void time_ascii() {
+        makeUnicodeRange(0, 0x7f, mNoOfBytes / 0x80);
+    }
+
+    @Test
+    public void time_bmp2() {
+        makeUnicodeRange(0x0080, 0x07ff, mNoOfBytes / 2 / 0x780);
+    }
+
+    @Test
+    public void time_bmp3() {
+        makeUnicodeRange(
+                0x0800,
+                0xffff,
+                mNoOfBytes / 3 / 0xf000 /* 0x10000 - 0x0800 - no of surrogate code points */);
+    }
+
+    @Test
+    public void time_supplementary() {
+        makeUnicodeRange(0x10000, 0x10ffff, mNoOfBytes / 4 / 0x100000);
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java
new file mode 100644
index 0000000..1d33fcb
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.zip.Adler32;
+import java.util.zip.CRC32;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ChecksumPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeAdler_block() throws Exception {
+        byte[] bytes = new byte[10000];
+        Adler32 adler = new Adler32();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            adler.update(bytes);
+        }
+    }
+
+    @Test
+    public void timeAdler_byte() throws Exception {
+        Adler32 adler = new Adler32();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            adler.update(1);
+        }
+    }
+
+    @Test
+    public void timeCrc_block() throws Exception {
+        byte[] bytes = new byte[10000];
+        CRC32 crc = new CRC32();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            crc.update(bytes);
+        }
+    }
+
+    @Test
+    public void timeCrc_byte() throws Exception {
+        CRC32 crc = new CRC32();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            crc.update(1);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java
new file mode 100644
index 0000000..35730ec
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+/** CipherInputStream benchmark. */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CipherInputStreamPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final int DATA_SIZE = 1024 * 1024;
+    private static final byte[] DATA = new byte[DATA_SIZE];
+
+    private static final int IV_SIZE = 16;
+    private static final byte[] IV = new byte[IV_SIZE];
+
+    static {
+        for (int i = 0; i < DATA_SIZE; i++) {
+            DATA[i] = (byte) i;
+        }
+        for (int i = 0; i < IV_SIZE; i++) {
+            IV[i] = (byte) i;
+        }
+    }
+
+    private SecretKey mKey;
+
+    private byte[] mOutput = new byte[8192];
+
+    private Cipher mCipherEncrypt;
+
+    private AlgorithmParameterSpec mSpec;
+
+    @Before
+    public void setUp() throws Exception {
+        KeyGenerator generator = KeyGenerator.getInstance("AES");
+        generator.init(128);
+        mKey = generator.generateKey();
+
+        mSpec = new IvParameterSpec(IV);
+
+        mCipherEncrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
+        mCipherEncrypt.init(Cipher.ENCRYPT_MODE, mKey, mSpec);
+    }
+
+    @Test
+    public void timeEncrypt() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mCipherEncrypt.init(Cipher.ENCRYPT_MODE, mKey, mSpec);
+            InputStream is = new CipherInputStream(new ByteArrayInputStream(DATA), mCipherEncrypt);
+            while (is.read(mOutput) != -1) {
+                // Keep iterating
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java
new file mode 100644
index 0000000..15c27f2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * Cipher benchmarks. Only runs on AES currently because of the combinatorial explosion of the test
+ * as it stands.
+ */
+@RunWith(Parameterized.class)
+@LargeTest
+public class CipherPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameterized.Parameters(
+            name =
+                    "mMode({0}), mPadding({1}), mKeySize({2}), mInputSize({3}),"
+                            + " mImplementation({4})")
+    public static Collection cases() {
+        int[] mKeySizes = new int[] {128, 192, 256};
+        int[] inputSizes = new int[] {16, 32, 64, 128, 1024, 8192};
+        final List<Object[]> params = new ArrayList<>();
+        for (Mode mode : Mode.values()) {
+            for (Padding padding : Padding.values()) {
+                for (Implementation implementation : Implementation.values()) {
+                    if ((mode == Mode.CBC
+                                    || mode == Mode.CFB
+                                    || mode == Mode.CTR
+                                    || mode == Mode.ECB
+                                    || mode == Mode.OFB)
+                            && padding == Padding.PKCS1PADDING) {
+                        continue;
+                    }
+                    if ((mode == Mode.CFB || mode == Mode.OFB)
+                            && padding == Padding.NOPADDING
+                            && implementation == Implementation.OpenSSL) {
+                        continue;
+                    }
+                    for (int mKeySize : mKeySizes) {
+                        for (int inputSize : inputSizes) {
+                            params.add(
+                                    new Object[] {
+                                        mode, padding, mKeySize, inputSize, implementation
+                                    });
+                        }
+                    }
+                }
+            }
+        }
+        return params;
+    }
+
+    private static final int DATA_SIZE = 8192;
+    private static final byte[] DATA = new byte[DATA_SIZE];
+
+    private static final int IV_SIZE = 16;
+
+    private static final byte[] IV = new byte[IV_SIZE];
+
+    static {
+        for (int i = 0; i < DATA_SIZE; i++) {
+            DATA[i] = (byte) i;
+        }
+        for (int i = 0; i < IV_SIZE; i++) {
+            IV[i] = (byte) i;
+        }
+    }
+
+    public Algorithm mAlgorithm = Algorithm.AES;
+
+    public enum Algorithm {
+        AES,
+    };
+
+    @Parameterized.Parameter(0)
+    public Mode mMode;
+
+    public enum Mode {
+        CBC,
+        CFB,
+        CTR,
+        ECB,
+        OFB,
+    };
+
+    @Parameterized.Parameter(1)
+    public Padding mPadding;
+
+    public enum Padding {
+        NOPADDING,
+        PKCS1PADDING,
+    };
+
+    @Parameterized.Parameter(2)
+    public int mKeySize;
+
+    @Parameterized.Parameter(3)
+    public int mInputSize;
+
+    @Parameterized.Parameter(4)
+    public Implementation mImplementation;
+
+    public enum Implementation {
+        OpenSSL,
+        BouncyCastle
+    };
+
+    private String mProviderName;
+
+    // Key generation isn't part of the benchmark so cache the results
+    private static Map<Integer, SecretKey> sKeySizes = new HashMap<Integer, SecretKey>();
+
+    private String mCipherAlgorithm;
+    private SecretKey mKey;
+
+    private byte[] mOutput = new byte[DATA.length];
+
+    private Cipher mCipherEncrypt;
+
+    private Cipher mCipherDecrypt;
+
+    private AlgorithmParameterSpec mSpec;
+
+    @Before
+    public void setUp() throws Exception {
+        mCipherAlgorithm =
+                mAlgorithm.toString() + "/" + mMode.toString() + "/" + mPadding.toString();
+
+        String mKeyAlgorithm = mAlgorithm.toString();
+        mKey = sKeySizes.get(mKeySize);
+        if (mKey == null) {
+            KeyGenerator generator = KeyGenerator.getInstance(mKeyAlgorithm);
+            generator.init(mKeySize);
+            mKey = generator.generateKey();
+            sKeySizes.put(mKeySize, mKey);
+        }
+
+        switch (mImplementation) {
+            case OpenSSL:
+                mProviderName = "AndroidOpenSSL";
+                break;
+            case BouncyCastle:
+                mProviderName = "BC";
+                break;
+            default:
+                throw new RuntimeException(mImplementation.toString());
+        }
+
+        if (mMode != Mode.ECB) {
+            mSpec = new IvParameterSpec(IV);
+        }
+
+        mCipherEncrypt = Cipher.getInstance(mCipherAlgorithm, mProviderName);
+        mCipherEncrypt.init(Cipher.ENCRYPT_MODE, mKey, mSpec);
+
+        mCipherDecrypt = Cipher.getInstance(mCipherAlgorithm, mProviderName);
+        mCipherDecrypt.init(Cipher.DECRYPT_MODE, mKey, mSpec);
+    }
+
+    @Test
+    public void timeEncrypt() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mCipherEncrypt.doFinal(DATA, 0, mInputSize, mOutput);
+        }
+    }
+
+    @Test
+    public void timeDecrypt() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mCipherDecrypt.doFinal(DATA, 0, mInputSize, mOutput);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java
new file mode 100644
index 0000000..6728e73
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.Collator;
+import java.text.RuleBasedCollator;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CollatorPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final RuleBasedCollator COLLATOR =
+            (RuleBasedCollator) Collator.getInstance(Locale.US);
+
+    @Test
+    public void timeCollatorPrimary() {
+        COLLATOR.setStrength(Collator.PRIMARY);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            COLLATOR.compare("abcde", "abcdf");
+            COLLATOR.compare("abcde", "abcde");
+            COLLATOR.compare("abcdf", "abcde");
+        }
+    }
+
+    @Test
+    public void timeCollatorSecondary() {
+        COLLATOR.setStrength(Collator.SECONDARY);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            COLLATOR.compare("abcdÂ", "abcdÄ");
+            COLLATOR.compare("abcdÂ", "abcdÂ");
+            COLLATOR.compare("abcdÄ", "abcdÂ");
+        }
+    }
+
+    @Test
+    public void timeCollatorTertiary() {
+        COLLATOR.setStrength(Collator.TERTIARY);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            COLLATOR.compare("abcdE", "abcde");
+            COLLATOR.compare("abcde", "abcde");
+            COLLATOR.compare("abcde", "abcdE");
+        }
+    }
+
+    @Test
+    public void timeCollatorIdentical() {
+        COLLATOR.setStrength(Collator.IDENTICAL);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            COLLATOR.compare("abcdȪ", "abcdȫ");
+            COLLATOR.compare("abcdȪ", "abcdȪ");
+            COLLATOR.compare("abcdȫ", "abcdȪ");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java
new file mode 100644
index 0000000..a89efff
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class CollectionsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Parameters(name = "mArrayListLength({0})")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {{4}, {16}, {64}, {256}, {1024}});
+    }
+
+    @Parameterized.Parameter(0)
+    public int arrayListLength;
+
+    public static Comparator<Integer> REVERSE =
+            new Comparator<Integer>() {
+                @Override
+                public int compare(Integer lhs, Integer rhs) {
+                    int lhsAsInt = lhs.intValue();
+                    int rhsAsInt = rhs.intValue();
+                    return rhsAsInt < lhsAsInt ? -1 : (lhsAsInt == rhsAsInt ? 0 : 1);
+                }
+            };
+
+    @Test
+    public void timeSort_arrayList() throws Exception {
+        List<Integer> input = buildList(arrayListLength, ArrayList.class);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Collections.sort(input);
+        }
+    }
+
+    @Test
+    public void timeSortWithComparator_arrayList() throws Exception {
+        List<Integer> input = buildList(arrayListLength, ArrayList.class);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Collections.sort(input, REVERSE);
+        }
+    }
+
+    @Test
+    public void timeSort_vector() throws Exception {
+        List<Integer> input = buildList(arrayListLength, Vector.class);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Collections.sort(input);
+        }
+    }
+
+    @Test
+    public void timeSortWithComparator_vector() throws Exception {
+        List<Integer> input = buildList(arrayListLength, Vector.class);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Collections.sort(input, REVERSE);
+        }
+    }
+
+    private static <T extends List<Integer>> List<Integer> buildList(
+            int arrayListLength, Class<T> listClass) throws Exception {
+        Random random = new Random();
+        random.setSeed(0);
+        List<Integer> list = listClass.newInstance();
+        for (int i = 0; i < arrayListLength; ++i) {
+            list.add(random.nextInt());
+        }
+        return list;
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java
new file mode 100644
index 0000000..4dba139
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public final class DateFormatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private Locale mLocale1;
+    private Locale mLocale2;
+    private Locale mLocale3;
+    private Locale mLocale4;
+
+    @Before
+    public void setUp() throws Exception {
+        mLocale1 = Locale.TAIWAN;
+        mLocale2 = Locale.GERMANY;
+        mLocale3 = Locale.FRANCE;
+        mLocale4 = Locale.ITALY;
+    }
+
+    @Test
+    public void timeGetDateTimeInstance() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DateFormat.getDateTimeInstance();
+        }
+    }
+
+    @Test
+    public void timeGetDateTimeInstance_multiple() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, mLocale1);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, mLocale2);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, mLocale3);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, mLocale4);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java
new file mode 100644
index 0000000..f3eddab
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DecimalFormatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static final String EXP_PATTERN = "##E0";
+
+    private static final DecimalFormat DF = (DecimalFormat) DecimalFormat.getInstance();
+    // Keep PATTERN_INSTANCE for timing with patterns, to not dirty the plain instance.
+    private static final DecimalFormat PATTERN_INSTANCE = (DecimalFormat)
+            DecimalFormat.getInstance();
+    private static final DecimalFormat DF_CURRENCY_US = (DecimalFormat)
+            NumberFormat.getCurrencyInstance(Locale.US);
+    private static final DecimalFormat DF_CURRENCY_FR = (DecimalFormat)
+            NumberFormat.getInstance(Locale.FRANCE);
+
+    private static final BigDecimal BD10E3 = new BigDecimal("10E3");
+    private static final BigDecimal BD10E9 = new BigDecimal("10E9");
+    private static final BigDecimal BD10E100 = new BigDecimal("10E100");
+    private static final BigDecimal BD10E1000 = new BigDecimal("10E1000");
+
+    private static final int WHOLE_NUMBER = 10;
+    private static final double TWO_DP_NUMBER = 3.14;
+
+    public void formatWithGrouping(Object obj) {
+        DF.setGroupingSize(3);
+        DF.setGroupingUsed(true);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DF.format(obj);
+        }
+    }
+
+    public void format(String pattern, Object obj) {
+        PATTERN_INSTANCE.applyPattern(pattern);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            PATTERN_INSTANCE.format(obj);
+        }
+    }
+
+    public void format(Object obj) {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DF.format(obj);
+        }
+    }
+
+    public void formatToCharacterIterator(Object obj) {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DF.formatToCharacterIterator(obj);
+        }
+    }
+
+
+    public void formatCurrencyUS(Object obj) {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DF_CURRENCY_US.format(obj);
+        }
+    }
+
+    public void formatCurrencyFR(Object obj) {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DF_CURRENCY_FR.format(obj);
+        }
+    }
+
+    @Test
+    public void time_formatGrouping_BigDecimal10e3() {
+        formatWithGrouping(BD10E3);
+    }
+
+    @Test
+    public void time_formatGrouping_BigDecimal10e9() {
+        formatWithGrouping(BD10E9);
+    }
+
+    @Test
+    public void time_formatGrouping_BigDecimal10e100() {
+        formatWithGrouping(BD10E100);
+    }
+
+    @Test
+    public void time_formatGrouping_BigDecimal10e1000() {
+        formatWithGrouping(BD10E1000);
+    }
+
+    @Test
+    public void time_formatBigDecimal10e3() {
+        format(BD10E3);
+    }
+
+    @Test
+    public void time_formatBigDecimal10e9() {
+        format(BD10E9);
+    }
+
+    @Test
+    public void time_formatBigDecimal10e100() {
+        format(BD10E100);
+    }
+
+    @Test
+    public void time_formatBigDecimal10e1000() {
+        format(BD10E1000);
+    }
+
+    @Test
+    public void time_formatPi() {
+        format(Math.PI);
+    }
+
+    @Test
+    public void time_formatE() {
+        format(Math.E);
+    }
+
+    @Test
+    public void time_formatUSD() {
+        formatCurrencyUS(WHOLE_NUMBER);
+    }
+
+    @Test
+    public void time_formatUsdWithCents() {
+        formatCurrencyUS(TWO_DP_NUMBER);
+    }
+
+    @Test
+    public void time_formatEur() {
+        formatCurrencyFR(WHOLE_NUMBER);
+    }
+
+    @Test
+    public void time_formatEurWithCents() {
+        formatCurrencyFR(TWO_DP_NUMBER);
+    }
+
+    @Test
+    public void time_formatAsExponent10e3() {
+        format(EXP_PATTERN, BD10E3);
+    }
+
+    @Test
+    public void time_formatAsExponent10e9() {
+        format(EXP_PATTERN, BD10E9);
+    }
+
+    @Test
+    public void time_formatAsExponent10e100() {
+        format(EXP_PATTERN, BD10E100);
+    }
+
+    @Test
+    public void time_formatAsExponent10e1000() {
+        format(EXP_PATTERN, BD10E1000);
+    }
+
+    @Test
+    public void time_formatToCharacterIterator10e3() {
+        formatToCharacterIterator(BD10E3);
+    }
+
+    @Test
+    public void time_formatToCharacterIterator10e9() {
+        formatToCharacterIterator(BD10E9);
+    }
+
+    @Test
+    public void time_formatToCharacterIterator10e100() {
+        formatToCharacterIterator(BD10E100);
+    }
+
+    @Test
+    public void time_formatToCharacterIterator10e1000() {
+        formatToCharacterIterator(BD10E1000);
+    }
+
+    @Test
+    public void time_instantiation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new DecimalFormat();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java
new file mode 100644
index 0000000..2bf0418
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DecimalFormatSymbolsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static Locale sLocale = Locale.getDefault(Locale.Category.FORMAT);
+
+    @Test
+    public void time_instantiation() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new DecimalFormatSymbols(sLocale);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java
new file mode 100644
index 0000000..c3320a4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.charset.Charset;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DefaultCharsetPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void time_defaultCharset() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Charset.defaultCharset();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java
new file mode 100644
index 0000000..7c52ac4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DnsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeDns() throws Exception {
+        String[] hosts = new String[] {
+                "www.amazon.com",
+                "z-ecx.images-amazon.com",
+                "g-ecx.images-amazon.com",
+                "ecx.images-amazon.com",
+                "ad.doubleclick.com",
+                "bpx.a9.com",
+                "d3dtik4dz1nej0.cloudfront.net",
+                "uac.advertising.com",
+                "servedby.advertising.com",
+                "view.atdmt.com",
+                "rmd.atdmt.com",
+                "spe.atdmt.com",
+                "www.google.com",
+                "www.cnn.com",
+                "bad.host.mtv.corp.google.com",
+        };
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        int i = 0;
+        while (state.keepRunning()) {
+            try {
+                InetAddress.getByName(hosts[++i % hosts.length]);
+            } catch (UnknownHostException ex) {
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java
new file mode 100644
index 0000000..d133359
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DoPrivilegedPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeDirect() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            String lineSeparator = System.getProperty("line.separator");
+        }
+    }
+
+    @Test
+    public void timeFastAndSlow() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            String lineSeparator;
+            if (System.getSecurityManager() == null) {
+                lineSeparator = System.getProperty("line.separator");
+            } else {
+                lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                    public String run() {
+                        return System.getProperty("line.separator");
+                    }
+                });
+            }
+        }
+    }
+
+    @Test
+    public void timeNewAction() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            String lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("line.separator");
+                }
+            });
+        }
+    }
+
+    @Test
+    public void timeReusedAction() throws Exception {
+        final PrivilegedAction<String> action = new ReusableAction("line.separator");
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            String lineSeparator = AccessController.doPrivileged(action);
+        }
+    }
+
+    private static final class ReusableAction implements PrivilegedAction<String> {
+        private final String mPropertyName;
+
+        ReusableAction(String propertyName) {
+            this.mPropertyName = propertyName;
+        }
+
+        public String run() {
+            return System.getProperty(mPropertyName);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java
new file mode 100644
index 0000000..38904af
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DoublePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private double mD = 1.2;
+    private long mL = 4608083138725491507L;
+
+    @Test
+    public void timeDoubleToLongBits() {
+        long result = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Double.doubleToLongBits(mD);
+        }
+        if (result != mL) {
+            throw new RuntimeException(Long.toString(result));
+        }
+    }
+
+    @Test
+    public void timeDoubleToRawLongBits() {
+        long result = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Double.doubleToRawLongBits(mD);
+        }
+        if (result != mL) {
+            throw new RuntimeException(Long.toString(result));
+        }
+    }
+
+    @Test
+    public void timeLongBitsToDouble() {
+        double result = 123.0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Double.longBitsToDouble(mL);
+        }
+        if (result != mD) {
+            throw new RuntimeException(Double.toString(result) + " "
+                    + Double.doubleToRawLongBits(result));
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java
new file mode 100644
index 0000000..4ff3ba5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public final class EqualsHashCodePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private enum Type {
+        URI() {
+            @Override Object newInstance(String text) throws Exception {
+                return new URI(text);
+            }
+        },
+        URL() {
+            @Override Object newInstance(String text) throws Exception {
+                return new URL(text);
+            }
+        };
+        abstract Object newInstance(String text) throws Exception;
+    }
+
+    private static final String QUERY = "%E0%AE%A8%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%AE%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%AF%E0%AE%AE%E0%AE%BE%E0%AE%A9%2C+%E0%AE%9A%E0%AF%81%E0%AE%B5%E0%AE%BE%E0%AE%B0%E0%AE%B8%E0%AF%8D%E0%AE%AF%E0%AE%AE%E0%AE%BE%E0%AE%A9+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D%2C+%E0%AE%86%E0%AE%A9%E0%AE%BE%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%A8%E0%AF%87%E0%AE%B0%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AF%82%E0%AE%B4%E0%AF%8D%E0%AE%A8%E0%AE%BF%E0%AE%B2%E0%AF%88+%E0%AE%8F%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%8E%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AE%BE%E0%AE%B2%E0%AF%8D+%E0%AE%AA%E0%AE%A3%E0%AE%BF%E0%AE%AF%E0%AF%88%E0%AE%AF%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%B5%E0%AE%B2%E0%AE%BF+%E0%AE%85%E0%AE%B5%E0%AE%B0%E0%AF%88+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%AA%E0%AF%86%E0%AE%B0%E0%AE%BF%E0%AE%AF+%E0%AE%95%E0%AF%86%E0%AE%BE%E0%AE%B3%E0%AF%8D%E0%AE%AE%E0%AF%81%E0%AE%A4%E0%AE%B2%E0%AF%8D+%E0%AE%AE%E0%AF%81%E0%AE%9F%E0%AE%BF%E0%AE%AF%E0%AF%81%E0%AE%AE%E0%AF%8D.+%E0%AE%85%E0%AE%A4%E0%AF%81+%E0%AE%9A%E0%AE%BF%E0%AE%B2+%E0%AE%A8%E0%AE%A9%E0%AF%8D%E0%AE%AE%E0%AF%88%E0%AE%95%E0%AE%B3%E0%AF%88+%E0%AE%AA%E0%AF%86%E0%AE%B1+%E0%AE%A4%E0%AE%B5%E0%AE%BF%E0%AE%B0%2C+%E0%AE%8E%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%A4%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%89%E0%AE%B4%E0%AF%88%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%89%E0%AE%9F%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AE%AF%E0%AE%BF%E0%AE%B1%E0%AF%8D%E0%AE%9A%E0%AE%BF+%E0%AE%AE%E0%AF%87%E0%AE%B1%E0%AF%8D%E0%AE%95%E0%AF%86%E0%AE%BE%E0%AE%B3%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AE%A4%E0%AF%81+%E0%AE%8E%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81+%E0%AE%87%E0%AE%A4%E0%AF%81+%E0%AE%92%E0%AE%B0%E0%AF%81+%E0%AE%9A%E0%AE%BF%E0%AE%B1%E0%AE%BF%E0%AE%AF+%E0%AE%89%E0%AE%A4%E0%AE%BE%E0%AE%B0%E0%AE%A3%E0%AE%AE%E0%AF%8D%2C+%E0%AE%8E%E0%AE%9F%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95.+%E0%AE%B0%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%8E%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%B5%E0%AE%BF%E0%AE%B3%E0%AF%88%E0%AE%B5%E0%AE%BE%E0%AE%95+%E0%AE%87%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%AE%E0%AF%8D+%E0%AE%86%E0%AE%A9%E0%AF%8D%E0%AE%B2%E0%AF%88%E0%AE%A9%E0%AF%8D+%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%BE%E0%AE%9F%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%B5%E0%AF%87%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%AF%E0%AE%BE%E0%AE%B0%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%B5%E0%AE%B1%E0%AF%81+%E0%AE%95%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AF%81%E0%AE%AA%E0%AE%BF%E0%AE%9F%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95+%E0%AE%B5%E0%AE%B0%E0%AF%81%E0%AE%AE%E0%AF%8D+%E0%AE%A8%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%A4%E0%AE%B1%E0%AF%8D%E0%AE%AA%E0%AF%87%E0%AE%BE%E0%AE%A4%E0%AF%81+%E0%AE%87%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D.+%E0%AE%87%E0%AE%A8%E0%AF%8D%E0%AE%A4+%E0%AE%A8%E0%AE%BF%E0%AE%95%E0%AE%B4%E0%AF%8D%E0%AE%B5%E0%AF%81%E0%AE%95%E0%AE%B3%E0%AE%BF%E0%AE%B2%E0%AF%8D+%E0%AE%9A%E0%AF%86%E0%AE%AF%E0%AF%8D%E0%AE%A4%E0%AE%AA%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%85%E0%AE%AE%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%BF%E0%AE%A9%E0%AF%8D+%E0%AE%95%E0%AE%A3%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81%2C+%E0%AE%85%E0%AE%B5%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%A4%E0%AE%B5%E0%AE%B1%E0%AF%81+%E0%AE%B5%E0%AE%BF%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AF%81+quae+%E0%AE%AA%E0%AE%9F%E0%AF%8D%E0%AE%9F%E0%AE%B1%E0%AF%88+%E0%AE%A8%E0%AF%80%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%B3%E0%AF%8D+%E0%AE%AA%E0%AE%B0%E0%AE%BF%E0%AE%A8%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B0%E0%AF%88%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%B1%E0%AF%87%E0%AE%BE%E0%AE%AE%E0%AF%8D+%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%95+%E0%AE%AE%E0%AE%BE%E0%AE%B1%E0%AF%81%E0%AE%AE%E0%AF%8D";
+
+    @Parameterized.Parameters(name = "mType({0})")
+    public static Collection cases() {
+        final List<Object[]> params = new ArrayList<>();
+        for (Type type : Type.values()) {
+            params.add(new Object[]{type});
+        }
+        return params;
+    }
+
+    @Parameterized.Parameter(0)
+    public Type mType;
+
+    Object mA1;
+    Object mA2;
+    Object mB1;
+    Object mB2;
+
+    Object mC1;
+    Object mC2;
+
+    @Before
+    public void setUp() throws Exception {
+        mA1 = mType.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
+        mA2 = mType.newInstance("https://mail.google.com/mail/u/0/?shva=1#inbox");
+        mB1 = mType.newInstance("http://developer.android.com/reference/java/net/URI.html");
+        mB2 = mType.newInstance("http://developer.android.com/reference/java/net/URI.html");
+
+        mC1 = mType.newInstance("http://developer.android.com/query?q=" + QUERY);
+        // Replace the very last char.
+        mC2 = mType.newInstance("http://developer.android.com/query?q=" + QUERY.substring(0, QUERY.length() - 3) + "%AF");
+    }
+
+    @Test
+    public void timeEquals() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mA1.equals(mB1);
+            mA1.equals(mA2);
+            mB1.equals(mB2);
+        }
+    }
+
+    @Test
+    public void timeHashCode() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mA1.hashCode();
+            mB1.hashCode();
+        }
+    }
+
+    @Test
+    public void timeEqualsWithHeavilyEscapedComponent() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mC1.equals(mC2);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
new file mode 100644
index 0000000..03c9d43
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.Collator;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+/**
+ * Benchmarks creation and cloning various expensive objects.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ExpensiveObjectsPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeNewDateFormatTimeInstance() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+            df.format(System.currentTimeMillis());
+        }
+    }
+
+    @Test
+    public void timeClonedDateFormatTimeInstance() {
+        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            ((DateFormat) df.clone()).format(System.currentTimeMillis());
+        }
+    }
+
+    @Test
+    public void timeReusedDateFormatTimeInstance() {
+        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            synchronized (df) {
+                df.format(System.currentTimeMillis());
+            }
+        }
+    }
+
+    @Test
+    public void timeNewCollator() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Collator.getInstance(Locale.US);
+        }
+    }
+
+    @Test
+    public void timeClonedCollator() {
+        Collator c = Collator.getInstance(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            c.clone();
+        }
+    }
+
+    @Test
+    public void timeNewDateFormatSymbols() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new DateFormatSymbols(Locale.US);
+        }
+    }
+
+    @Test
+    public void timeClonedDateFormatSymbols() {
+        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            dfs.clone();
+        }
+    }
+
+    @Test
+    public void timeNewDecimalFormatSymbols() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new DecimalFormatSymbols(Locale.US);
+        }
+    }
+
+    @Test
+    public void timeClonedDecimalFormatSymbols() {
+        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            dfs.clone();
+        }
+    }
+
+    @Test
+    public void timeNewNumberFormat() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            NumberFormat.getInstance(Locale.US);
+        }
+    }
+
+    @Test
+    public void timeClonedNumberFormat() {
+        NumberFormat nf = NumberFormat.getInstance(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            nf.clone();
+        }
+    }
+
+    @Test
+    public void timeLongToString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Long.toString(1024L);
+        }
+    }
+
+    @Test
+    public void timeNumberFormatTrivialFormatDouble() {
+        NumberFormat nf = NumberFormat.getInstance(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            nf.format(1024.0);
+        }
+    }
+
+    @Test
+    public void timeNewSimpleDateFormat() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new SimpleDateFormat();
+        }
+    }
+
+    @Test
+    public void timeClonedSimpleDateFormat() {
+        SimpleDateFormat sdf = new SimpleDateFormat();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            sdf.clone();
+        }
+    }
+
+    @Test
+    public void timeNewGregorianCalendar() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new GregorianCalendar();
+        }
+    }
+
+    @Test
+    public void timeClonedGregorianCalendar() {
+        GregorianCalendar gc = new GregorianCalendar();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            gc.clone();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java
new file mode 100644
index 0000000..783136a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public final class FilePerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeFileCreationWithEmptyChild() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new File("/foo", "/");
+        }
+    }
+
+    @Test
+    public void timeFileCreationWithNormalizationNecessary() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            new File("/foo//bar//baz//bag", "/baz/");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java
new file mode 100644
index 0000000..a995f5c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class FloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private float mFloat = 1.2f;
+    private int mInt = 1067030938;
+
+    @Test
+    public void timeFloatToIntBits() {
+        int result = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Float.floatToIntBits(mFloat);
+        }
+        if (result != mInt) {
+            throw new RuntimeException(Integer.toString(result));
+        }
+    }
+
+    @Test
+    public void timeFloatToRawIntBits() {
+        int result = 123;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Float.floatToRawIntBits(mFloat);
+        }
+        if (result != mInt) {
+            throw new RuntimeException(Integer.toString(result));
+        }
+    }
+
+    @Test
+    public void timeIntBitsToFloat() {
+        float result = 123.0f;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            result = Float.intBitsToFloat(mInt);
+        }
+        if (result != mFloat) {
+            throw new RuntimeException(Float.toString(result) + " "
+                    + Float.floatToRawIntBits(result));
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java
new file mode 100644
index 0000000..94c4f08
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Formatter;
+import java.util.Locale;
+
+/**
+ * Compares Formatter against hand-written StringBuilder code.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class FormatterPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeFormatter_NoFormatting() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that doesn't actually need any formatting");
+        }
+    }
+
+    @Test
+    public void timeStringBuilder_NoFormatting() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("this is a reasonably short string that doesn't actually need formatting");
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneInt() {
+        Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that has an int %d in it", value);
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneIntArabic() {
+        Locale arabic = new Locale("ar");
+        Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format(arabic, "this is a reasonably short string that has an int %d in it", value);
+        }
+    }
+
+    @Test
+    public void timeStringBuilder_OneInt() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("this is a reasonably short string that has an int ");
+            sb.append(1024);
+            sb.append(" in it");
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneHexInt() {
+        Integer value = Integer.valueOf(1024); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that has an int %x in it", value);
+        }
+    }
+
+    @Test
+    public void timeStringBuilder_OneHexInt() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("this is a reasonably short string that has an int ");
+            sb.append(Integer.toHexString(1024));
+            sb.append(" in it");
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneFloat() {
+        Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that has a float %f in it", value);
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneFloat_dot2f() {
+        Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that has a float %.2f in it", value);
+        }
+    }
+
+    @Test
+    public void timeFormatter_TwoFloats() {
+        Float value = Float.valueOf(10.24f); // We're not trying to benchmark boxing here.
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a short string that has two floats %f and %f in it", value, value);
+        }
+    }
+
+    @Test
+    public void timeStringBuilder_OneFloat() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("this is a reasonably short string that has a float ");
+            sb.append(10.24f);
+            sb.append(" in it");
+        }
+    }
+
+    @Test
+    public void timeFormatter_OneString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Formatter f = new Formatter();
+            f.format("this is a reasonably short string that has a string %s in it", "hello");
+        }
+    }
+
+    @Test
+    public void timeStringBuilder_OneString() {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("this is a reasonably short string that has a string ");
+            sb.append("hello");
+            sb.append(" in it");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java
new file mode 100644
index 0000000..5ff2b22
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+/**
+ * Benchmarks creation and cloning various expensive objects.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class NumberFormatTrivialFormatLongPerfTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeNumberFormatTrivialFormatLong() {
+        NumberFormat nf = NumberFormat.getInstance(Locale.US);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            nf.format(1024L);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..e7bb8f8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectGetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    int mValue;
+
+    public ReflectGetFieldLittleEndianIntPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("mValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mField.getInt(this);
+            x = (int) mField.getInt(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..5bac46a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectGetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    String mValue;
+
+    public ReflectGetFieldLittleEndianStringPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("mValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mField.get(this);
+            x = (String) mField.get(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..1005a70
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectGetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    static int sValue;
+
+    public ReflectGetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("sValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mField.getInt(null);
+            x = (int) mField.getInt(null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..5224ad3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectGetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    static String sValue;
+
+    public ReflectGetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("sValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mField.get(null);
+            x = (String) mField.get(null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..06696ef
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectSetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    int mValue;
+
+    public ReflectSetFieldLittleEndianIntPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("mValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.setInt(this, 42);
+            mField.setInt(this, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..a784c52
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectSetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    String mValue;
+
+    public ReflectSetFieldLittleEndianStringPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("mValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.set(this, "qwerty");
+            mField.set(this, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..4ce0078
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectSetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    static int sValue;
+
+    public ReflectSetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("sValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.setInt(null, 42);
+            mField.setInt(null, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..587e201
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ReflectSetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    static String sValue;
+
+    public ReflectSetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mField = this.getClass().getDeclaredField("sValue");
+    }
+
+    @Test
+    public void run() throws Throwable {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mField.set(null, "qwerty");
+            mField.set(null, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..e06b534
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchangeAcquire(this, mField, ~42);
+            x = (int) mVh.compareAndExchangeAcquire(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..0fd16a0
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchangeAcquire(this, mField, null);
+            x = (String) mVh.compareAndExchangeAcquire(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..7ad42d0
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchangeAcquire(sField, ~42);
+            x = (int) mVh.compareAndExchangeAcquire(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..76e1f47
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest()
+            throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchangeAcquire(sField, null);
+            x = (String) mVh.compareAndExchangeAcquire(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..b4b7840
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchange(this, mField, ~42);
+            x = (int) mVh.compareAndExchange(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..09ed167
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchange(this, mField, null);
+            x = (String) mVh.compareAndExchange(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..920d2e4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchangeRelease(this, mField, ~42);
+            x = (int) mVh.compareAndExchangeRelease(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..55ed789
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchangeRelease(this, mField, null);
+            x = (String) mVh.compareAndExchangeRelease(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..ea3057b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchangeRelease(sField, ~42);
+            x = (int) mVh.compareAndExchangeRelease(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..20558aa9
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest()
+            throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchangeRelease(sField, null);
+            x = (String) mVh.compareAndExchangeRelease(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..d7b1d29
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.compareAndExchange(sField, ~42);
+            x = (int) mVh.compareAndExchange(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..d138dc9
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.compareAndExchange(sField, null);
+            x = (String) mVh.compareAndExchange(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..36153f2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandsetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandsetFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.compareAndSet(this, mField, ~42);
+            success = mVh.compareAndSet(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..bf4fbc4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandsetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandsetFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.compareAndSet(this, mField, null);
+            success = mVh.compareAndSet(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..d3c1b36
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.compareAndSet(sField, ~42);
+            success = mVh.compareAndSet(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..90e69a1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.compareAndSet(sField, null);
+            success = mVh.compareAndSet(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..96bc104
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getAcquire(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAcquire(this);
+            x = (int) mVh.getAcquire(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..2679494
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetAcquireFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetAcquireFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getAcquire(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAcquire(this);
+            x = (String) mVh.getAcquire(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..170dce7
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getAcquire();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAcquire();
+            x = (int) mVh.getAcquire();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..11d12db
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getAcquire();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAcquire();
+            x = (String) mVh.getAcquire();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..bd2a600
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetArrayLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int ELEMENT_VALUE = 42;
+    int[] mArray = {ELEMENT_VALUE};
+    VarHandle mVh;
+
+    public VarHandleGetArrayLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.arrayElementVarHandle(int[].class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.get(mArray, 0);
+        if (v != ELEMENT_VALUE) {
+            throw new RuntimeException("array element has unexpected value: " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int[] a = mArray;
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.get(a, 0);
+            x = (int) mVh.get(a, 0);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..99a09cd
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetArrayLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String ELEMENT_VALUE = "qwerty";
+    String[] mArray = {ELEMENT_VALUE};
+    VarHandle mVh;
+
+    public VarHandleGetArrayLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.arrayElementVarHandle(String[].class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.get(mArray, 0);
+        if (v != ELEMENT_VALUE) {
+            throw new RuntimeException("array element has unexpected value: " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String[] a = mArray;
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.get(a, 0);
+            x = (String) mVh.get(a, 0);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java
new file mode 100644
index 0000000..db83606
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetByteArrayViewBigEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int VALUE = 42;
+    byte[] mArray1 = {
+        (byte) (VALUE >> 24), (byte) (VALUE >> 16), (byte) (VALUE >> 8), (byte) VALUE
+    };
+    byte[] mArray2 = {(byte) (-1 >> 24), (byte) (-1 >> 16), (byte) (-1 >> 8), (byte) VALUE};
+    VarHandle mVh;
+
+    public VarHandleGetByteArrayViewBigEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.BIG_ENDIAN);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.get(mArray1, 0);
+        if (v != VALUE) {
+            throw new RuntimeException("array has unexpected value: " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        byte[] a = mArray1;
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.get(a, 0);
+            x = (int) mVh.get(a, 0);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..4a8f924
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetByteArrayViewLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int VALUE = 42;
+    byte[] mArray1 = {
+        (byte) VALUE, (byte) (VALUE >> 8), (byte) (VALUE >> 16), (byte) (VALUE >> 24)
+    };
+    byte[] mArray2 = {(byte) VALUE, (byte) (-1 >> 8), (byte) (-1 >> 16), (byte) (-1 >> 24)};
+    VarHandle mVh;
+
+    public VarHandleGetByteArrayViewLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.LITTLE_ENDIAN);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.get(mArray1, 0);
+        if (v != VALUE) {
+            throw new RuntimeException("array has unexpected value: " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        byte[] a = mArray1;
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.get(a, 0);
+            x = (int) mVh.get(a, 0);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..4e4a9ee
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.get(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.get(this);
+            x = (int) mVh.get(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..3e7de1d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.get(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.get(this);
+            x = (String) mVh.get(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..67d53b3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetOpaqueFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetOpaqueFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getOpaque(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getOpaque(this);
+            x = (int) mVh.getOpaque(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..470a1ce
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetOpaqueFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetOpaqueFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getOpaque(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getOpaque(this);
+            x = (String) mVh.getOpaque(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8a982c2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getOpaque();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getOpaque();
+            x = (int) mVh.getOpaque();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..2c17a69
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getOpaque();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getOpaque();
+            x = (String) mVh.getOpaque();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..099b1f4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.get();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.get();
+            x = (int) mVh.get();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..7f6b4b8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.get();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.get();
+            x = (String) mVh.get();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8592d30
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetVolatileFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetVolatileFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getVolatile(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getVolatile(this);
+            x = (int) mVh.getVolatile(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..539bd2a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetVolatileFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetVolatileFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getVolatile(this);
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getVolatile(this);
+            x = (String) mVh.getVolatile(this);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..a36a7b6
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Before
+    public void setup() {
+        int v = (int) mVh.getVolatile();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getVolatile();
+            x = (int) mVh.getVolatile();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..90d2a70
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Before
+    public void setup() {
+        String v = (String) mVh.getVolatile();
+        if (v != FIELD_VALUE) {
+            throw new RuntimeException("field has unexpected value " + v);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getVolatile();
+            x = (String) mVh.getVolatile();
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..4e5fcf3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    float mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAddAcquire(this, 2.17f);
+            x = (float) mVh.getAndAddAcquire(this, 2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..fd0abf8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAddAcquire(this, ~42);
+            x = (int) mVh.getAndAddAcquire(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..9272b11
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    static float sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAddAcquire(2.17f);
+            x = (float) mVh.getAndAddAcquire(2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..a896d0a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAddAcquire(~42);
+            x = (int) mVh.getAndAddAcquire(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..671b0a3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    float mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAdd(this, 2.17f);
+            x = (float) mVh.getAndAdd(this, 2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..1eb3f92
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAdd(this, ~42);
+            x = (int) mVh.getAndAdd(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..f23d5e2
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    float mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAddRelease(this, 2.17f);
+            x = (float) mVh.getAndAddRelease(this, 2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..1613798
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAddRelease(this, ~42);
+            x = (int) mVh.getAndAddRelease(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..14f1c00
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    static float sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAddRelease(2.17f);
+            x = (float) mVh.getAndAddRelease(2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8327caf
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAddRelease(~42);
+            x = (int) mVh.getAndAddRelease(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java
new file mode 100644
index 0000000..6c211fb
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final float FIELD_VALUE = 3.14f;
+    static float sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", float.class);
+    }
+
+    @Test
+    public void run() {
+        float x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (float) mVh.getAndAdd(2.17f);
+            x = (float) mVh.getAndAdd(2.17f);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..d02cd73
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandaddStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandaddStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndAdd(~42);
+            x = (int) mVh.getAndAdd(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..0777586
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAndAcquire(this, ~42);
+            x = (int) mVh.getAndBitwiseAndAcquire(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..24a949f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAndAcquire(~42);
+            x = (int) mVh.getAndBitwiseAndAcquire(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..4b94bbe
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAnd(this, ~42);
+            x = (int) mVh.getAndBitwiseAnd(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..1784c05
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAndRelease(this, ~42);
+            x = (int) mVh.getAndBitwiseAndRelease(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..f85d3ee
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAndRelease(~42);
+            x = (int) mVh.getAndBitwiseAndRelease(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..81f6779
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseAnd(~42);
+            x = (int) mVh.getAndBitwiseAnd(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..9436fad
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOrAcquire(this, ~42);
+            x = (int) mVh.getAndBitwiseOrAcquire(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..9ebc458
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOrAcquire(~42);
+            x = (int) mVh.getAndBitwiseOrAcquire(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..ea159a1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOr(this, ~42);
+            x = (int) mVh.getAndBitwiseOr(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..a42ec7e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOrRelease(this, ~42);
+            x = (int) mVh.getAndBitwiseOrRelease(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..6f1007e5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOrRelease(~42);
+            x = (int) mVh.getAndBitwiseOrRelease(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..6a73818
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseOr(~42);
+            x = (int) mVh.getAndBitwiseOr(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..e9a365b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXorAcquire(this, ~42);
+            x = (int) mVh.getAndBitwiseXorAcquire(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..fc9191c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXorAcquire(~42);
+            x = (int) mVh.getAndBitwiseXorAcquire(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..5919a1d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXor(this, ~42);
+            x = (int) mVh.getAndBitwiseXor(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..313e580
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXorRelease(this, ~42);
+            x = (int) mVh.getAndBitwiseXorRelease(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..9c8b3ae
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXorRelease(~42);
+            x = (int) mVh.getAndBitwiseXorRelease(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..ea618cc
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndBitwiseXor(~42);
+            x = (int) mVh.getAndBitwiseXor(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..df6f470
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSetAcquire(this, ~42);
+            x = (int) mVh.getAndSetAcquire(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..63fd740
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSetAcquire(this, null);
+            x = (String) mVh.getAndSetAcquire(this, null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..a96031e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSetAcquire(~42);
+            x = (int) mVh.getAndSetAcquire(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..3bc25fb
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSetAcquire(null);
+            x = (String) mVh.getAndSetAcquire(null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..7ffdf11
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSet(this, ~42);
+            x = (int) mVh.getAndSet(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..cc7f3be
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSet(this, null);
+            x = (String) mVh.getAndSet(this, null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8d54c00
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSetRelease(this, ~42);
+            x = (int) mVh.getAndSetRelease(this, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..22e92dd
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSetRelease(this, null);
+            x = (String) mVh.getAndSetRelease(this, null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..08ddc8b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSetRelease(~42);
+            x = (int) mVh.getAndSetRelease(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..429e090
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSetRelease(null);
+            x = (String) mVh.getAndSetRelease(null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..d5b31f6
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (int) mVh.getAndSet(~42);
+            x = (int) mVh.getAndSet(~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..8667aaa
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleGetandsetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleGetandsetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            x = (String) mVh.getAndSet(null);
+            x = (String) mVh.getAndSet(null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..aa20246
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetArrayLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int ELEMENT_VALUE = 42;
+    int[] mArray = {ELEMENT_VALUE};
+    VarHandle mVh;
+
+    public VarHandleSetArrayLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.arrayElementVarHandle(int[].class);
+    }
+
+    @After
+    public void teardown() {
+        if (mArray[0] != ~42) {
+            throw new RuntimeException("array element has unexpected value: " + mArray[0]);
+        }
+    }
+
+    @Test
+    public void run() {
+        int[] a = mArray;
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(a, 0, ~42);
+            mVh.set(a, 0, ~42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..9e0210f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetArrayLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String ELEMENT_VALUE = "qwerty";
+    String[] mArray = {ELEMENT_VALUE};
+    VarHandle mVh;
+
+    public VarHandleSetArrayLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.arrayElementVarHandle(String[].class);
+    }
+
+    @After
+    public void teardown() {
+        if (mArray[0] != null) {
+            throw new RuntimeException("array element has unexpected value: " + mArray[0]);
+        }
+    }
+
+    @Test
+    public void run() {
+        String[] a = mArray;
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(a, 0, null);
+            mVh.set(a, 0, null);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java
new file mode 100644
index 0000000..d489168
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetByteArrayViewBigEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int VALUE = 42;
+    byte[] mArray1 = {
+        (byte) (VALUE >> 24), (byte) (VALUE >> 16), (byte) (VALUE >> 8), (byte) VALUE
+    };
+    byte[] mArray2 = {(byte) (-1 >> 24), (byte) (-1 >> 16), (byte) (-1 >> 8), (byte) VALUE};
+    VarHandle mVh;
+
+    public VarHandleSetByteArrayViewBigEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.BIG_ENDIAN);
+    }
+
+    @After
+    public void teardown() {
+        if (!Arrays.equals(mArray2, mArray1)) {
+            throw new RuntimeException(
+                    "array has unexpected values: "
+                            + mArray2[0]
+                            + " "
+                            + mArray2[1]
+                            + " "
+                            + mArray2[2]
+                            + " "
+                            + mArray2[3]);
+        }
+    }
+
+    @Test
+    public void run() {
+        byte[] a = mArray2;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(a, 0, VALUE);
+            mVh.set(a, 0, VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..b06d7ef
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetByteArrayViewLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int VALUE = 42;
+    byte[] mArray1 = {
+        (byte) VALUE, (byte) (VALUE >> 8), (byte) (VALUE >> 16), (byte) (VALUE >> 24)
+    };
+    byte[] mArray2 = {(byte) VALUE, (byte) (-1 >> 8), (byte) (-1 >> 16), (byte) (-1 >> 24)};
+    VarHandle mVh;
+
+    public VarHandleSetByteArrayViewLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.byteArrayViewVarHandle(int[].class, ByteOrder.LITTLE_ENDIAN);
+    }
+
+    @After
+    public void teardown() {
+        if (!Arrays.equals(mArray2, mArray1)) {
+            throw new RuntimeException(
+                    "array has unexpected values: "
+                            + mArray2[0]
+                            + " "
+                            + mArray2[1]
+                            + " "
+                            + mArray2[2]
+                            + " "
+                            + mArray2[3]);
+        }
+    }
+
+    @Test
+    public void run() {
+        byte[] a = mArray2;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(a, 0, VALUE);
+            mVh.set(a, 0, VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8446937
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(this, FIELD_VALUE);
+            mVh.set(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..34540a3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(this, FIELD_VALUE);
+            mVh.set(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..c79b513
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetOpaqueFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetOpaqueFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setOpaque(this, FIELD_VALUE);
+            mVh.setOpaque(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..028130d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetOpaqueFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetOpaqueFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setOpaque(this, FIELD_VALUE);
+            mVh.setOpaque(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..06a5a8c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setOpaque(FIELD_VALUE);
+            mVh.setOpaque(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..78eefc8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setOpaque(FIELD_VALUE);
+            mVh.setOpaque(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..cd1bd48
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setRelease(this, FIELD_VALUE);
+            mVh.setRelease(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..6c0740c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetReleaseFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetReleaseFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setRelease(this, FIELD_VALUE);
+            mVh.setRelease(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..b95f24b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setRelease(FIELD_VALUE);
+            mVh.setRelease(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..b03cf82
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setRelease(FIELD_VALUE);
+            mVh.setRelease(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..c98c092
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(FIELD_VALUE);
+            mVh.set(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..625cfc7
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.set(FIELD_VALUE);
+            mVh.set(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..58319b3
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetVolatileFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetVolatileFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setVolatile(this, FIELD_VALUE);
+            mVh.setVolatile(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..f741542
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetVolatileFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetVolatileFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (mField != FIELD_VALUE) {
+            throw new RuntimeException("mField has unexpected value " + mField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setVolatile(this, FIELD_VALUE);
+            mVh.setVolatile(this, FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..87f6a78
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        int x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setVolatile(FIELD_VALUE);
+            mVh.setVolatile(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..610345f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @After
+    public void teardown() {
+        if (sField != FIELD_VALUE) {
+            throw new RuntimeException("sField has unexpected value " + sField);
+        }
+    }
+
+    @Test
+    public void run() {
+        String x;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            mVh.setVolatile(FIELD_VALUE);
+            mVh.setVolatile(FIELD_VALUE);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..519d4fd
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetAcquire(this, mField, ~42);
+            success = mVh.weakCompareAndSetAcquire(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..322cf63
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetAcquire(this, mField, null);
+            success = mVh.weakCompareAndSetAcquire(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..f8ccbad
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetAcquire(sField, ~42);
+            success = mVh.weakCompareAndSetAcquire(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..16f1059
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest()
+            throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetAcquire(sField, null);
+            success = mVh.weakCompareAndSetAcquire(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..c7084fe
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSet(this, mField, ~42);
+            success = mVh.weakCompareAndSet(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..9d526b8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSet(this, mField, null);
+            success = mVh.weakCompareAndSet(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..8372f6c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetPlain(this, mField, ~42);
+            success = mVh.weakCompareAndSetPlain(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..87e47e7
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetPlain(this, mField, null);
+            success = mVh.weakCompareAndSetPlain(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..aa2e104
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetPlain(sField, ~42);
+            success = mVh.weakCompareAndSetPlain(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..ebaa080
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetPlain(sField, null);
+            success = mVh.weakCompareAndSetPlain(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..d90356a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    int mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetRelease(this, mField, ~42);
+            success = mVh.weakCompareAndSetRelease(this, mField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..6db995a
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    String mField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findVarHandle(this.getClass(), "mField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetRelease(this, mField, null);
+            success = mVh.weakCompareAndSetRelease(this, mField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..ecea19e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetRelease(sField, ~42);
+            success = mVh.weakCompareAndSetRelease(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..ab86284
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest()
+            throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSetRelease(sField, null);
+            success = mVh.weakCompareAndSetRelease(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java
new file mode 100644
index 0000000..23a33f5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final int FIELD_VALUE = 42;
+    static int sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", int.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSet(sField, ~42);
+            success = mVh.weakCompareAndSet(sField, 42);
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java
new file mode 100644
index 0000000..270b5ad
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// This file is generated by generate_java.py do not directly modify!
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest {
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final String FIELD_VALUE = "qwerty";
+    static String sField = FIELD_VALUE;
+    VarHandle mVh;
+
+    public VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest() throws Throwable {
+        mVh = MethodHandles.lookup().findStaticVarHandle(this.getClass(), "sField", String.class);
+    }
+
+    @Test
+    public void run() {
+        boolean success;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            success = mVh.weakCompareAndSet(sField, null);
+            success = mVh.weakCompareAndSet(sField, "qwerty");
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/generate_java.py b/apct-tests/perftests/core/src/android/libcore/varhandles/generate_java.py
new file mode 100755
index 0000000..f3a1fff
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/generate_java.py
@@ -0,0 +1,515 @@
+#!/usr/bin/python3
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Generate java benchmarks for varhandles.
+Adapted to use CrystalBall from art/test/2239-varhandle-perf/util-src/generate_java.py.
+
+To run use: python generate_java.py <destination_directory>
+
+And then to correct lint errors (from frameworks/base):
+../../tools/repohooks/tools/google-java-format.py --fix --sort-imports  --google-java-format-diff ../../external/google-java-format/scripts/google-java-format-diff.py
+"""
+
+
+from enum import Enum
+from pathlib import Path
+
+import io
+import sys
+
+
+class MemLoc(Enum):
+    FIELD = 0
+    ARRAY = 1
+    BYTE_ARRAY_VIEW = 2
+
+
+def to_camel_case(word):
+    return ''.join(c for c in word.title() if not c == '_')
+
+
+LOOP ="BenchmarkState state = mPerfStatusReporter.getBenchmarkState();\n        while (state.keepRunning())"
+
+class Benchmark:
+    def __init__(self, code, static, vartype, flavour, klass, method, memloc,
+        byteorder="LITTLE_ENDIAN"):
+        self.code = code
+        self.static = static
+        self.vartype = vartype
+        self.flavour = flavour
+        self.klass = klass
+        self.method = method
+        self.byteorder = byteorder
+        self.memloc = memloc
+
+    def fullname(self):
+        return "{klass}{method}{flavour}{static_name}{memloc}{byteorder}{vartype}PerfTest".format(
+            klass = self.klass,
+            method = to_camel_case(self.method),
+            flavour = self.flavour,
+            static_name = "Static" if self.static else "",
+            memloc = to_camel_case(self.memloc.name),
+            byteorder = to_camel_case(self.byteorder),
+            vartype = to_camel_case(self.vartype))
+
+    def gencode(self):
+        if self.klass == "Reflect":
+            method_suffix = "" if self.vartype == "String" else self.vartype.title()
+            static_first_arg = "null"
+        elif self.klass == "Unsafe":
+            method_suffix = "Object" if self.vartype == "String" else self.vartype.title()
+            static_first_arg = "this.getClass()"
+        else:
+            method_suffix = ""
+            static_first_arg = ""
+
+        first_arg = static_first_arg if self.static else "this"
+
+        return self.code.format(
+            name = self.fullname(),
+            method = self.method + method_suffix,
+            flavour = self.flavour,
+            static_name = "Static" if self.static else "",
+            static_kwd = "static " if self.static else "",
+            static_prefix = "s" if self.static else "m",
+            this = first_arg,
+            this_comma = "" if not first_arg else first_arg + ", ",
+            vartype = self.vartype,
+            byteorder = self.byteorder,
+            value1 = VALUES[self.vartype][0],
+            value2 = VALUES[self.vartype][1],
+            value1_byte_array = VALUES["byte[]"][self.byteorder][0],
+            value2_byte_array = VALUES["byte[]"][self.byteorder][1],
+            loop = LOOP)
+
+
+def BenchVHField(code, static, vartype, flavour, method):
+    return Benchmark(code, static, vartype, flavour, "VarHandle", method, MemLoc.FIELD)
+
+
+def BenchVHArray(code, vartype, flavour, method):
+    return Benchmark(code, False, vartype, flavour, "VarHandle", method, MemLoc.ARRAY)
+
+
+def BenchVHByteArrayView(code, byteorder, vartype, flavour, method):
+    return Benchmark(code, False, vartype, flavour, "VarHandle", method, MemLoc.BYTE_ARRAY_VIEW, byteorder)
+
+
+def BenchReflect(code, static, vartype, method):
+    return Benchmark(code, static, vartype, "", "Reflect", method, MemLoc.FIELD)
+
+
+def BenchUnsafe(code, static, vartype, method):
+    return Benchmark(code, static, vartype, "", "Unsafe", method, MemLoc.FIELD)
+
+
+VALUES = {
+    "int": ["42", "~42"],
+    "float": ["3.14f", "2.17f"],
+    "String": ["\"qwerty\"", "null"],
+    "byte[]": {
+        "LITTLE_ENDIAN": [
+            "{ (byte) VALUE, (byte) (VALUE >> 8), (byte) (VALUE >> 16), (byte) (VALUE >> 24) }",
+            "{ (byte) VALUE, (byte) (-1 >> 8), (byte) (-1 >> 16), (byte) (-1 >> 24) }",
+        ],
+        "BIG_ENDIAN": [
+            "{ (byte) (VALUE >> 24), (byte) (VALUE >> 16), (byte) (VALUE >> 8), (byte) VALUE }",
+            "{ (byte) (-1 >> 24), (byte) (-1 >> 16), (byte) (-1 >> 8), (byte) VALUE }",
+        ],
+    },
+}
+
+REPEAT = 2
+REPEAT_HALF = (int) (REPEAT / 2)
+
+
+BANNER = """/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ // This file is generated by generate_java.py do not directly modify!"""
+
+
+VH_IMPORTS = """
+package android.libcore.varhandles;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+"""
+
+
+VH_START = BANNER + VH_IMPORTS + """
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class {name} {{
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final {vartype} FIELD_VALUE = {value1};
+    {static_kwd}{vartype} {static_prefix}Field = FIELD_VALUE;
+    VarHandle mVh;
+
+    public {name}() throws Throwable {{
+        mVh = MethodHandles.lookup().find{static_name}VarHandle(this.getClass(), "{static_prefix}Field", {vartype}.class);
+    }}
+"""
+
+
+END = """
+        }}
+    }}
+}}"""
+
+
+VH_GET = VH_START + """
+    @Before
+    public void setup() {{
+        {vartype} v = ({vartype}) mVh.{method}{flavour}({this});
+        if (v != FIELD_VALUE) {{
+            throw new RuntimeException("field has unexpected value " + v);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}({this});""" * REPEAT + END
+
+
+VH_SET = VH_START + """
+    @After
+    public void teardown() {{
+        if ({static_prefix}Field != FIELD_VALUE) {{
+            throw new RuntimeException("{static_prefix}Field has unexpected value " + {static_prefix}Field);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        {vartype} x;
+        {loop} {{""" + """
+            mVh.{method}{flavour}({this_comma}FIELD_VALUE);""" * REPEAT + END
+
+
+VH_CAS = VH_START + """
+    @Test
+    public void run() {{
+        boolean success;
+        {loop} {{""" + """
+            success = mVh.{method}{flavour}({this_comma}{static_prefix}Field, {value2});
+            success = mVh.{method}{flavour}({this_comma}{static_prefix}Field, {value1});""" * REPEAT_HALF + END
+
+
+VH_CAE = VH_START + """
+    @Test
+    public void run() {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}({this_comma}{static_prefix}Field, {value2});
+            x = ({vartype}) mVh.{method}{flavour}({this_comma}{static_prefix}Field, {value1});""" * REPEAT_HALF + END
+
+
+VH_GAS = VH_START + """
+    @Test
+    public void run() {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END
+
+
+VH_GAA = VH_START + """
+    @Test
+    public void run() {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END
+
+
+VH_GAB = VH_START + """
+    @Test
+    public void run() {{
+        int x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}({this_comma}{value2});""" * REPEAT + END
+
+
+VH_START_ARRAY = BANNER + VH_IMPORTS + """
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class {name} {{
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final {vartype} ELEMENT_VALUE = {value1};
+    {vartype}[] mArray = {{ ELEMENT_VALUE }};
+    VarHandle mVh;
+
+    public {name}() throws Throwable {{
+        mVh = MethodHandles.arrayElementVarHandle({vartype}[].class);
+    }}
+"""
+
+
+VH_GET_A = VH_START_ARRAY + """
+    @Before
+    public void setup() {{
+        {vartype} v = ({vartype}) mVh.{method}{flavour}(mArray, 0);
+        if (v != ELEMENT_VALUE) {{
+            throw new RuntimeException("array element has unexpected value: " + v);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        {vartype}[] a = mArray;
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}(a, 0);""" * REPEAT + END
+
+
+VH_SET_A = VH_START_ARRAY + """
+    @After
+    public void teardown() {{
+        if (mArray[0] != {value2}) {{
+            throw new RuntimeException("array element has unexpected value: " + mArray[0]);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        {vartype}[] a = mArray;
+        {vartype} x;
+        {loop} {{""" + """
+            mVh.{method}{flavour}(a, 0, {value2});""" * REPEAT + END
+
+
+VH_START_BYTE_ARRAY_VIEW = BANNER + VH_IMPORTS + """
+import java.util.Arrays;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class {name} {{
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    static final {vartype} VALUE = {value1};
+    byte[] mArray1 = {value1_byte_array};
+    byte[] mArray2 = {value2_byte_array};
+    VarHandle mVh;
+
+    public {name}() throws Throwable {{
+        mVh = MethodHandles.byteArrayViewVarHandle({vartype}[].class, ByteOrder.{byteorder});
+  }}
+"""
+
+
+VH_GET_BAV = VH_START_BYTE_ARRAY_VIEW + """
+    @Before
+    public void setup() {{
+        {vartype} v = ({vartype}) mVh.{method}{flavour}(mArray1, 0);
+        if (v != VALUE) {{
+            throw new RuntimeException("array has unexpected value: " + v);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        byte[] a = mArray1;
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mVh.{method}{flavour}(a, 0);""" * REPEAT + END
+
+
+VH_SET_BAV = VH_START_BYTE_ARRAY_VIEW + """
+    @After
+    public void teardown() {{
+        if (!Arrays.equals(mArray2, mArray1)) {{
+            throw new RuntimeException("array has unexpected values: " +
+                mArray2[0] + " " + mArray2[1] + " " + mArray2[2] + " " + mArray2[3]);
+        }}
+    }}
+
+    @Test
+    public void run() {{
+        byte[] a = mArray2;
+        {loop} {{""" + """
+            mVh.{method}{flavour}(a, 0, VALUE);""" * REPEAT + END
+
+
+REFLECT_START = BANNER + VH_IMPORTS + """
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class {name} {{
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    Field mField;
+    {static_kwd}{vartype} {static_prefix}Value;
+
+    public {name}() throws Throwable {{
+        mField = this.getClass().getDeclaredField("{static_prefix}Value");
+    }}
+"""
+
+
+REFLECT_GET = REFLECT_START + """
+    @Test
+    public void run() throws Throwable {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) mField.{method}({this});""" * REPEAT + END
+
+
+REFLECT_SET = REFLECT_START + """
+    @Test
+    public void run() throws Throwable {{
+        {loop} {{""" + """
+            mField.{method}({this_comma}{value1});""" * REPEAT + END
+
+
+UNSAFE_START = BANNER + VH_IMPORTS + """
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class {name} {{
+    @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    long mOffset;
+    public {static_kwd}{vartype} {static_prefix}Value = {value1};
+
+    {name}() throws Throwable {{
+        Field field = this.getClass().getDeclaredField("{static_prefix}Value");
+        mOffset = get{static_name}FieldOffset(field);
+    }}
+"""
+
+
+UNSAFE_GET = UNSAFE_START + """
+    @Test
+    public void run() throws Throwable {{
+        {vartype} x;
+        {loop} {{""" + """
+            x = ({vartype}) theUnsafe.{method}({this_comma}mOffset);""" * REPEAT + END
+
+
+UNSAFE_PUT = UNSAFE_START + """
+    @Test
+    public void run() throws Throwable {{
+        {loop} {{""" + """
+             theUnsafe.{method}({this_comma}mOffset, {value1});""" * REPEAT + END
+
+
+UNSAFE_CAS = UNSAFE_START + """
+    @Test
+    public void run() throws Throwable {{
+        {loop} {{""" + """
+           theUnsafe.{method}({this_comma}mOffset, {value1}, {value2});
+           theUnsafe.{method}({this_comma}mOffset, {value2}, {value1});""" * REPEAT_HALF + END
+
+
+ALL_BENCHMARKS = (
+    [BenchVHField(VH_GET, static, vartype, flavour, "get")
+        for flavour in ["", "Acquire", "Opaque", "Volatile"]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_SET, static, vartype, flavour, "set")
+        for flavour in ["", "Volatile", "Opaque", "Release"]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_CAS, static, vartype, flavour, "compareAndSet")
+        for flavour in [""]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_CAS, static, vartype, flavour, "weakCompareAndSet")
+        for flavour in ["", "Plain", "Acquire", "Release"]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_CAE, static, vartype, flavour, "compareAndExchange")
+        for flavour in ["", "Acquire", "Release"]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_GAS, static, vartype, flavour, "getAndSet")
+        for flavour in ["", "Acquire", "Release"]
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchVHField(VH_GAA, static, vartype, flavour, "getAndAdd")
+        for flavour in ["", "Acquire", "Release"]
+        for static in [True, False]
+        for vartype in ["int", "float"]] +
+    [BenchVHField(VH_GAB, static, vartype, flavour, "getAndBitwise")
+        for flavour in [oper + mode
+            for oper in ["Or", "Xor", "And"]
+            for mode in ["", "Acquire", "Release"]]
+        for static in [True, False]
+        for vartype in ["int"]] +
+    [BenchVHArray(VH_GET_A, vartype, flavour, "get")
+        for flavour in [""]
+        for vartype in ["int", "String"]] +
+    [BenchVHArray(VH_SET_A, vartype, flavour, "set")
+        for flavour in [""]
+        for vartype in ["int", "String"]] +
+    [BenchVHByteArrayView(VH_GET_BAV, byteorder, vartype, flavour, "get")
+        for flavour in [""]
+        for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"]
+        for vartype in ["int"]] +
+    [BenchVHByteArrayView(VH_SET_BAV, byteorder, vartype, flavour, "set")
+        for flavour in [""]
+        for byteorder in ["BIG_ENDIAN", "LITTLE_ENDIAN"]
+        for vartype in ["int"]] +
+    [BenchReflect(REFLECT_GET, static, vartype, "get")
+        for static in [True, False]
+        for vartype in ["int", "String"]] +
+    [BenchReflect(REFLECT_SET, static, vartype, "set")
+        for static in [True, False]
+        for vartype in ["int", "String"]])
+
+
+
+def main(argv):
+    final_java_dir = Path(argv[1])
+    if not final_java_dir.exists() or not final_java_dir.is_dir():
+        print("{} is not a valid java dir".format(final_java_dir), file=sys.stderr)
+        sys.exit(1)
+
+    for bench in ALL_BENCHMARKS:
+        file_path = final_java_dir / "{}.java".format(bench.fullname())
+        with file_path.open("w") as f:
+            print(bench.gencode(), file=f)
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/api/api.go b/api/api.go
index 9cd0132..93f1354 100644
--- a/api/api.go
+++ b/api/api.go
@@ -179,7 +179,7 @@
 	// Note: order matters: first parameter is the full api-versions.xml
 	// after that the stubs files in any order
 	// stubs files are all modules that export API surfaces EXCEPT ART
-	props.Srcs = append([]string{":framework-doc-stubs{.api_versions.xml}"}, createSrcs(modules, ".stubs{.jar}")...)
+	props.Srcs = append([]string{":api_versions_public{.api_versions.xml}"}, createSrcs(modules, ".stubs{.jar}")...)
 	props.Dists = []android.Dist{{Targets: []string{"sdk"}}}
 	ctx.CreateModule(genrule.GenRuleFactory, &props)
 }
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 52fd7be..6582623 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -509,7 +509,8 @@
     resolution = limitSurfaceSize(resolution.width, resolution.height);
     // create the native surface
     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
-            resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
+            resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565,
+            ISurfaceComposerClient::eOpaque);
 
     SurfaceComposerClient::Transaction t;
 
diff --git a/core/api/current.txt b/core/api/current.txt
index 641b1a3..2e0e6e57 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11473,7 +11473,7 @@
     field public static final String FEATURE_CAMERA_LEVEL_FULL = "android.hardware.camera.level.full";
     field public static final String FEATURE_CANT_SAVE_STATE = "android.software.cant_save_state";
     field public static final String FEATURE_COMPANION_DEVICE_SETUP = "android.software.companion_device_setup";
-    field public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
+    field @Deprecated public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
     field public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
     field public static final String FEATURE_CONTROLS = "android.software.controls";
     field public static final String FEATURE_DEVICE_ADMIN = "android.software.device_admin";
@@ -11544,12 +11544,18 @@
     field public static final String FEATURE_SIP = "android.software.sip";
     field public static final String FEATURE_SIP_VOIP = "android.software.sip.voip";
     field public static final String FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+    field public static final String FEATURE_TELECOM = "android.software.telecom";
     field public static final String FEATURE_TELEPHONY = "android.hardware.telephony";
+    field public static final String FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
     field public static final String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+    field public static final String FEATURE_TELEPHONY_DATA = "android.hardware.telephony.data";
     field public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
     field public static final String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
     field public static final String FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
     field public static final String FEATURE_TELEPHONY_MBMS = "android.hardware.telephony.mbms";
+    field public static final String FEATURE_TELEPHONY_MESSAGING = "android.hardware.telephony.messaging";
+    field public static final String FEATURE_TELEPHONY_RADIO_ACCESS = "android.hardware.telephony.radio";
+    field public static final String FEATURE_TELEPHONY_SUBSCRIPTION = "android.hardware.telephony.subscription";
     field @Deprecated public static final String FEATURE_TELEVISION = "android.hardware.type.television";
     field public static final String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
     field public static final String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
@@ -21438,6 +21444,7 @@
     field public static final String KEY_VIDEO_QP_P_MAX = "video-qp-p-max";
     field public static final String KEY_VIDEO_QP_P_MIN = "video-qp-p-min";
     field public static final String KEY_WIDTH = "width";
+    field public static final String LOG_SESSION_ID = "log-session-id";
     field public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
     field public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3";
     field public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4";
@@ -29612,6 +29619,7 @@
     field public static final int S = 31; // 0x1f
     field public static final int S_V2 = 32; // 0x20
     field public static final int TIRAMISU = 10000; // 0x2710
+    field public static final int UPSIDE_DOWN_CAKE = 10000; // 0x2710
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -30066,6 +30074,7 @@
 
   public static interface IBinder.DeathRecipient {
     method public void binderDied();
+    method public default void binderDied(@NonNull android.os.IBinder);
   }
 
   public interface IInterface {
@@ -41214,8 +41223,11 @@
     field public static final String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
     field public static final String MMS_CONFIG_USER_AGENT = "userAgent";
     field public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; // 0x7
+    field public static final int MMS_ERROR_DATA_DISABLED = 11; // 0xb
     field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
+    field public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10; // 0xa
     field public static final int MMS_ERROR_INVALID_APN = 2; // 0x2
+    field public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9; // 0x9
     field public static final int MMS_ERROR_IO_ERROR = 5; // 0x5
     field public static final int MMS_ERROR_NO_DATA_NETWORK = 8; // 0x8
     field public static final int MMS_ERROR_RETRY = 6; // 0x6
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 9db3cdc..fd87a61 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -100,10 +100,12 @@
     field public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2; // 0x2
     field public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1; // 0xffffffff
     field public static final int USB_HAL_NOT_SUPPORTED = -1; // 0xffffffff
+    field public static final int USB_HAL_RETRY = -2; // 0xfffffffe
     field public static final int USB_HAL_V1_0 = 10; // 0xa
     field public static final int USB_HAL_V1_1 = 11; // 0xb
     field public static final int USB_HAL_V1_2 = 12; // 0xc
     field public static final int USB_HAL_V1_3 = 13; // 0xd
+    field public static final int USB_HAL_V2_0 = 20; // 0x14
   }
 
 }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 95fc7ec..abc2b74 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4169,8 +4169,14 @@
   }
 
   public final class UsbPort {
+    method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
     method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
+    field public static final int ENABLE_USB_DATA_ERROR_INTERNAL = 1; // 0x1
+    field public static final int ENABLE_USB_DATA_ERROR_NOT_SUPPORTED = 2; // 0x2
+    field public static final int ENABLE_USB_DATA_ERROR_OTHER = 4; // 0x4
+    field public static final int ENABLE_USB_DATA_ERROR_PORT_MISMATCH = 3; // 0x3
+    field public static final int ENABLE_USB_DATA_SUCCESS = 0; // 0x0
   }
 
   public final class UsbPortStatus implements android.os.Parcelable {
diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java
index a7c0e5c..a7828ab 100644
--- a/core/java/android/app/time/ExternalTimeSuggestion.java
+++ b/core/java/android/app/time/ExternalTimeSuggestion.java
@@ -19,15 +19,14 @@
 import android.annotation.CurrentTimeMillisLong;
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.app.timedetector.TimeSuggestionHelper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Objects;
 
@@ -75,7 +74,9 @@
     public static final @NonNull Creator<ExternalTimeSuggestion> CREATOR =
             new Creator<ExternalTimeSuggestion>() {
                 public ExternalTimeSuggestion createFromParcel(Parcel in) {
-                    return ExternalTimeSuggestion.createFromParcel(in);
+                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
+                            ExternalTimeSuggestion.class, in);
+                    return new ExternalTimeSuggestion(helper);
                 }
 
                 public ExternalTimeSuggestion[] newArray(int size) {
@@ -83,10 +84,7 @@
                 }
             };
 
-    @NonNull
-    private final TimestampedValue<Long> mUnixEpochTime;
-    @Nullable
-    private ArrayList<String> mDebugInfo;
+    @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
 
     /**
      * Creates a time suggestion cross-referenced to the elapsed realtime clock. See {@link
@@ -98,17 +96,12 @@
      */
     public ExternalTimeSuggestion(@ElapsedRealtimeLong long elapsedRealtimeMillis,
             @CurrentTimeMillisLong long suggestionMillis) {
-        mUnixEpochTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis);
+        mTimeSuggestionHelper = new TimeSuggestionHelper(ExternalTimeSuggestion.class,
+                new TimestampedValue<>(elapsedRealtimeMillis, suggestionMillis));
     }
 
-    private static ExternalTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
-        ExternalTimeSuggestion suggestion =
-                new ExternalTimeSuggestion(utcTime.getReferenceTimeMillis(), utcTime.getValue());
-        @SuppressWarnings("unchecked")
-        ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
-        suggestion.mDebugInfo = debugInfo;
-        return suggestion;
+    private ExternalTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
+        mTimeSuggestionHelper = Objects.requireNonNull(helper);
     }
 
     @Override
@@ -118,8 +111,7 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUnixEpochTime, 0);
-        dest.writeList(mDebugInfo);
+        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
     }
 
     /**
@@ -127,7 +119,7 @@
      */
     @NonNull
     public TimestampedValue<Long> getUnixEpochTime() {
-        return mUnixEpochTime;
+        return mTimeSuggestionHelper.getUnixEpochTime();
     }
 
     /**
@@ -135,9 +127,7 @@
      */
     @NonNull
     public List<String> getDebugInfo() {
-        return mDebugInfo == null
-                ? Collections.emptyList()
-                : Collections.unmodifiableList(mDebugInfo);
+        return mTimeSuggestionHelper.getDebugInfo();
     }
 
     /**
@@ -146,10 +136,7 @@
      * #equals(Object)} and {@link #hashCode()}.
      */
     public void addDebugInfo(@NonNull String... debugInfos) {
-        if (mDebugInfo == null) {
-            mDebugInfo = new ArrayList<>();
-        }
-        mDebugInfo.addAll(Arrays.asList(debugInfos));
+        mTimeSuggestionHelper.addDebugInfo(debugInfos);
     }
 
     @Override
@@ -161,18 +148,29 @@
             return false;
         }
         ExternalTimeSuggestion that = (ExternalTimeSuggestion) o;
-        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
+        return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUnixEpochTime);
+        return mTimeSuggestionHelper.hashCode();
     }
 
     @Override
     public String toString() {
-        return "ExternalTimeSuggestion{" + "mUnixEpochTime=" + mUnixEpochTime
-                + ", mDebugInfo=" + mDebugInfo
-                + '}';
+        return mTimeSuggestionHelper.handleToString();
+    }
+
+    /** @hide */
+    public static ExternalTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        return new ExternalTimeSuggestion(
+                TimeSuggestionHelper.handleParseCommandLineArg(ExternalTimeSuggestion.class, cmd));
+    }
+
+    /** @hide */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        TimeSuggestionHelper.handlePrintCommandLineOpts(
+                pw, "External", ExternalTimeSuggestion.class);
     }
 }
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/core/java/android/app/timedetector/GnssTimeSuggestion.java
index 34f4565..3531b19 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.java
+++ b/core/java/android/app/timedetector/GnssTimeSuggestion.java
@@ -17,30 +17,19 @@
 package android.app.timedetector;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Objects;
 
 /**
  * A time signal from a GNSS source.
  *
- * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
- * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code
- * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code
- * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate
- * but it is volatile, so time suggestions cannot be persisted across device resets.
- *
- * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
- * record why the suggestion exists and how it was entered. This information exists only to aid in
- * debugging and therefore is used by {@link #toString()}, but it is not for use in detection
- * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ * <p>See {@link TimeSuggestionHelper} for property information.
  *
  * @hide
  */
@@ -49,7 +38,9 @@
     public static final @NonNull Creator<GnssTimeSuggestion> CREATOR =
             new Creator<GnssTimeSuggestion>() {
                 public GnssTimeSuggestion createFromParcel(Parcel in) {
-                    return GnssTimeSuggestion.createFromParcel(in);
+                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
+                            GnssTimeSuggestion.class, in);
+                    return new GnssTimeSuggestion(helper);
                 }
 
                 public GnssTimeSuggestion[] newArray(int size) {
@@ -57,21 +48,14 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
-    @Nullable private ArrayList<String> mDebugInfo;
+    @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
 
     public GnssTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
-        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
-        Objects.requireNonNull(unixEpochTime.getValue());
+        mTimeSuggestionHelper = new TimeSuggestionHelper(GnssTimeSuggestion.class, unixEpochTime);
     }
 
-    private static GnssTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
-        GnssTimeSuggestion suggestion = new GnssTimeSuggestion(unixEpochTime);
-        @SuppressWarnings("unchecked")
-        ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
-        suggestion.mDebugInfo = debugInfo;
-        return suggestion;
+    private GnssTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
+        mTimeSuggestionHelper = Objects.requireNonNull(helper);
     }
 
     @Override
@@ -81,19 +65,17 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUnixEpochTime, 0);
-        dest.writeList(mDebugInfo);
+        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
     }
 
     @NonNull
     public TimestampedValue<Long> getUnixEpochTime() {
-        return mUnixEpochTime;
+        return mTimeSuggestionHelper.getUnixEpochTime();
     }
 
     @NonNull
     public List<String> getDebugInfo() {
-        return mDebugInfo == null
-                ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+        return mTimeSuggestionHelper.getDebugInfo();
     }
 
     /**
@@ -102,10 +84,7 @@
      * {@link #equals(Object)} and {@link #hashCode()}.
      */
     public void addDebugInfo(String... debugInfos) {
-        if (mDebugInfo == null) {
-            mDebugInfo = new ArrayList<>();
-        }
-        mDebugInfo.addAll(Arrays.asList(debugInfos));
+        mTimeSuggestionHelper.addDebugInfo(debugInfos);
     }
 
     @Override
@@ -117,19 +96,29 @@
             return false;
         }
         GnssTimeSuggestion that = (GnssTimeSuggestion) o;
-        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
+        return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUnixEpochTime);
+        return mTimeSuggestionHelper.hashCode();
     }
 
     @Override
     public String toString() {
-        return "GnssTimeSuggestion{"
-                + "mUnixEpochTime=" + mUnixEpochTime
-                + ", mDebugInfo=" + mDebugInfo
-                + '}';
+        return mTimeSuggestionHelper.handleToString();
+    }
+
+    /** Parses command line args to create a {@link GnssTimeSuggestion}. */
+    public static GnssTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        TimeSuggestionHelper suggestionHelper =
+                TimeSuggestionHelper.handleParseCommandLineArg(GnssTimeSuggestion.class, cmd);
+        return new GnssTimeSuggestion(suggestionHelper);
+    }
+
+    /** Prints the command line args needed to create a {@link GnssTimeSuggestion}. */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        TimeSuggestionHelper.handlePrintCommandLineOpts(pw, "GNSS", GnssTimeSuggestion.class);
     }
 }
diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java
index 76db33b..b447799 100644
--- a/core/java/android/app/timedetector/ManualTimeSuggestion.java
+++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java
@@ -20,27 +20,17 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Objects;
 
 /**
  * A time signal from a manual (user provided) source.
  *
- * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
- * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code unixEpochTime.referenceTimeMillis}
- * is the value of the elapsed realtime clock when the {@code unixEpochTime.value} was established.
- * Note that the elapsed realtime clock is considered accurate but it is volatile, so time
- * suggestions cannot be persisted across device resets.
- *
- * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
- * record why the suggestion exists and how it was entered. This information exists only to aid in
- * debugging and therefore is used by {@link #toString()}, but it is not for use in detection
- * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ * <p>See {@link TimeSuggestionHelper} for property information.
  *
  * @hide
  */
@@ -49,7 +39,9 @@
     public static final @NonNull Creator<ManualTimeSuggestion> CREATOR =
             new Creator<ManualTimeSuggestion>() {
                 public ManualTimeSuggestion createFromParcel(Parcel in) {
-                    return ManualTimeSuggestion.createFromParcel(in);
+                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
+                            ManualTimeSuggestion.class, in);
+                    return new ManualTimeSuggestion(helper);
                 }
 
                 public ManualTimeSuggestion[] newArray(int size) {
@@ -57,21 +49,14 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
-    @Nullable private ArrayList<String> mDebugInfo;
+    @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
 
     public ManualTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
-        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
-        Objects.requireNonNull(unixEpochTime.getValue());
+        mTimeSuggestionHelper = new TimeSuggestionHelper(ManualTimeSuggestion.class, unixEpochTime);
     }
 
-    private static ManualTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
-        ManualTimeSuggestion suggestion = new ManualTimeSuggestion(unixEpochTime);
-        @SuppressWarnings("unchecked")
-        ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
-        suggestion.mDebugInfo = debugInfo;
-        return suggestion;
+    private ManualTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
+        mTimeSuggestionHelper = Objects.requireNonNull(helper);
     }
 
     @Override
@@ -81,19 +66,17 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUnixEpochTime, 0);
-        dest.writeList(mDebugInfo);
+        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
     }
 
     @NonNull
     public TimestampedValue<Long> getUnixEpochTime() {
-        return mUnixEpochTime;
+        return mTimeSuggestionHelper.getUnixEpochTime();
     }
 
     @NonNull
     public List<String> getDebugInfo() {
-        return mDebugInfo == null
-                ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+        return mTimeSuggestionHelper.getDebugInfo();
     }
 
     /**
@@ -102,10 +85,7 @@
      * {@link #equals(Object)} and {@link #hashCode()}.
      */
     public void addDebugInfo(String... debugInfos) {
-        if (mDebugInfo == null) {
-            mDebugInfo = new ArrayList<>();
-        }
-        mDebugInfo.addAll(Arrays.asList(debugInfos));
+        mTimeSuggestionHelper.addDebugInfo(debugInfos);
     }
 
     @Override
@@ -117,19 +97,28 @@
             return false;
         }
         ManualTimeSuggestion that = (ManualTimeSuggestion) o;
-        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
+        return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUnixEpochTime);
+        return mTimeSuggestionHelper.hashCode();
     }
 
     @Override
     public String toString() {
-        return "ManualTimeSuggestion{"
-                + "mUnixEpochTime=" + mUnixEpochTime
-                + ", mDebugInfo=" + mDebugInfo
-                + '}';
+        return mTimeSuggestionHelper.handleToString();
+    }
+
+    /** @hide */
+    public static ManualTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        return new ManualTimeSuggestion(
+                TimeSuggestionHelper.handleParseCommandLineArg(ManualTimeSuggestion.class, cmd));
+    }
+
+    /** @hide */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        TimeSuggestionHelper.handlePrintCommandLineOpts(pw, "Manual", ManualTimeSuggestion.class);
     }
 }
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
index e22f1d6e..e93c75c 100644
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java
+++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
@@ -17,31 +17,19 @@
 package android.app.timedetector;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.Objects;
 
 /**
  * A time signal from a network time source like NTP.
  *
- * <p>{@code unixEpochTime} contains the suggested time. The {@code unixEpochTime.value} is the
- * number of milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system.
- * The {@code unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when
- * the {@code unixEpochTime.value} was established. Note that the elapsed realtime clock is
- * considered accurate but it is volatile, so time suggestions cannot be persisted across device
- * resets.
- *
- * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
- * record why the suggestion exists and how it was determined. This information exists only to aid
- * in debugging and therefore is used by {@link #toString()}, but it is not for use in detection
- * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ * <p>See {@link TimeSuggestionHelper} for property information.
  *
  * @hide
  */
@@ -50,7 +38,9 @@
     public static final @NonNull Creator<NetworkTimeSuggestion> CREATOR =
             new Creator<NetworkTimeSuggestion>() {
                 public NetworkTimeSuggestion createFromParcel(Parcel in) {
-                    return NetworkTimeSuggestion.createFromParcel(in);
+                    TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
+                            NetworkTimeSuggestion.class, in);
+                    return new NetworkTimeSuggestion(helper);
                 }
 
                 public NetworkTimeSuggestion[] newArray(int size) {
@@ -58,21 +48,15 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
-    @Nullable private ArrayList<String> mDebugInfo;
+    @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
 
     public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
-        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
-        Objects.requireNonNull(unixEpochTime.getValue());
+        mTimeSuggestionHelper = new TimeSuggestionHelper(
+                NetworkTimeSuggestion.class, unixEpochTime);
     }
 
-    private static NetworkTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
-        NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(unixEpochTime);
-        @SuppressWarnings("unchecked")
-        ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
-        suggestion.mDebugInfo = debugInfo;
-        return suggestion;
+    private NetworkTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
+        mTimeSuggestionHelper = Objects.requireNonNull(helper);
     }
 
     @Override
@@ -82,35 +66,30 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUnixEpochTime, 0);
-        dest.writeList(mDebugInfo);
+        mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
     }
 
     @NonNull
     public TimestampedValue<Long> getUnixEpochTime() {
-        return mUnixEpochTime;
+        return mTimeSuggestionHelper.getUnixEpochTime();
     }
 
     @NonNull
     public List<String> getDebugInfo() {
-        return mDebugInfo == null
-                ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+        return mTimeSuggestionHelper.getDebugInfo();
     }
 
     /**
      * Associates information with the instance that can be useful for debugging / logging. The
-     * information is present in {@link #toString()} but is not considered for
-     * {@link #equals(Object)} and {@link #hashCode()}.
+     * information is present in {@link #toString()} but is not considered for {@link
+     * #equals(Object)} and {@link #hashCode()}.
      */
     public void addDebugInfo(String... debugInfos) {
-        if (mDebugInfo == null) {
-            mDebugInfo = new ArrayList<>();
-        }
-        mDebugInfo.addAll(Arrays.asList(debugInfos));
+        mTimeSuggestionHelper.addDebugInfo(debugInfos);
     }
 
     @Override
-    public boolean equals(@Nullable Object o) {
+    public boolean equals(Object o) {
         if (this == o) {
             return true;
         }
@@ -118,19 +97,28 @@
             return false;
         }
         NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
-        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
+        return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUnixEpochTime);
+        return mTimeSuggestionHelper.hashCode();
     }
 
     @Override
     public String toString() {
-        return "NetworkTimeSuggestion{"
-                + "mUnixEpochTime=" + mUnixEpochTime
-                + ", mDebugInfo=" + mDebugInfo
-                + '}';
+        return mTimeSuggestionHelper.handleToString();
+    }
+
+    /** @hide */
+    public static NetworkTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        return new NetworkTimeSuggestion(
+                TimeSuggestionHelper.handleParseCommandLineArg(NetworkTimeSuggestion.class, cmd));
+    }
+
+    /** @hide */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        TimeSuggestionHelper.handlePrintCommandLineOpts(pw, "Network", NetworkTimeSuggestion.class);
     }
 }
diff --git a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
index 4ff7517..6f204d6 100644
--- a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
+++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
@@ -20,8 +20,10 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -88,6 +90,61 @@
         return suggestion;
     }
 
+    /** @hide */
+    public static TelephonyTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        Integer slotIndex = null;
+        Long referenceTimeMillis = null;
+        Long unixEpochTimeMillis = null;
+        String opt;
+        while ((opt = cmd.getNextArg()) != null) {
+            switch (opt) {
+                case "--slot_index": {
+                    slotIndex = Integer.parseInt(cmd.getNextArgRequired());
+                    break;
+                }
+                case "--reference_time": {
+                    referenceTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                case "--unix_epoch_time": {
+                    unixEpochTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException("Unknown option: " + opt);
+                }
+            }
+        }
+
+        if (slotIndex == null) {
+            throw new IllegalArgumentException("No slotIndex specified.");
+        }
+        if (referenceTimeMillis == null) {
+            throw new IllegalArgumentException("No referenceTimeMillis specified.");
+        }
+        if (unixEpochTimeMillis == null) {
+            throw new IllegalArgumentException("No unixEpochTimeMillis specified.");
+        }
+
+        TimestampedValue<Long> timeSignal =
+                new TimestampedValue<>(referenceTimeMillis, unixEpochTimeMillis);
+        Builder builder = new Builder(slotIndex)
+                .setUnixEpochTime(timeSignal)
+                .addDebugInfo("Command line injection");
+        return builder.build();
+    }
+
+    /** @hide */
+    public static void printCommandLineOpts(PrintWriter pw) {
+        pw.println("Telephony suggestion options:");
+        pw.println("  --slot_index <number>");
+        pw.println("  --reference_time <elapsed realtime millis>");
+        pw.println("  --unix_epoch_time <Unix epoch time millis>");
+        pw.println();
+        pw.println("See " + TelephonyTimeSuggestion.class.getName() + " for more information");
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index a356230..f0d77761 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -44,6 +44,36 @@
     String SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED = "is_auto_detection_enabled";
 
     /**
+     * A shell command that injects a manual time suggestion.
+     * @hide
+     */
+    String SHELL_COMMAND_SUGGEST_MANUAL_TIME = "suggest_manual_time";
+
+    /**
+     * A shell command that injects a telephony time suggestion.
+     * @hide
+     */
+    String SHELL_COMMAND_SUGGEST_TELEPHONY_TIME = "suggest_telephony_time";
+
+    /**
+     * A shell command that injects a network time suggestion.
+     * @hide
+     */
+    String SHELL_COMMAND_SUGGEST_NETWORK_TIME = "suggest_network_time";
+
+    /**
+     * A shell command that injects a GNSS time suggestion.
+     * @hide
+     */
+    String SHELL_COMMAND_SUGGEST_GNSS_TIME = "suggest_gnss_time";
+
+    /**
+     * A shell command that injects a external time suggestion.
+     * @hide
+     */
+    String SHELL_COMMAND_SUGGEST_EXTERNAL_TIME = "suggest_external_time";
+
+    /**
      * A shared utility method to create a {@link ManualTimeSuggestion}.
      *
      * @hide
diff --git a/core/java/android/app/timedetector/TimeSuggestionHelper.java b/core/java/android/app/timedetector/TimeSuggestionHelper.java
new file mode 100644
index 0000000..9b99be6
--- /dev/null
+++ b/core/java/android/app/timedetector/TimeSuggestionHelper.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.timedetector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.ShellCommand;
+import android.os.TimestampedValue;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A delegate class to support time suggestion classes that could diverge in the future. This class
+ * exists purely for code re-use and provides support methods. It avoids class inheritance
+ * deliberately to allow each suggestion to evolve in different directions later without affecting
+ * SDK APIs.
+ *
+ * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code
+ * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code
+ * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate
+ * but it is volatile, so time suggestions cannot be persisted across device resets.
+ *
+ * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
+ * record why the suggestion exists and how it was entered. This information exists only to aid in
+ * debugging and therefore is used by {@link #toString()}, but it is not for use in detection
+ * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ *
+ * @hide
+ */
+public final class TimeSuggestionHelper {
+
+    @NonNull private final Class<?> mHelpedClass;
+    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
+    @Nullable private ArrayList<String> mDebugInfo;
+
+    /** Creates a helper for the specified class, containing the supplied properties. */
+    public TimeSuggestionHelper(@NonNull Class<?> helpedClass,
+            @NonNull TimestampedValue<Long> unixEpochTime) {
+        mHelpedClass = Objects.requireNonNull(helpedClass);
+        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+        Objects.requireNonNull(unixEpochTime.getValue());
+    }
+
+    /** See {@link TimeSuggestionHelper} for property details. */
+    @NonNull
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
+    }
+
+    /** See {@link TimeSuggestionHelper} for information about {@code debugInfo}. */
+    @NonNull
+    public List<String> getDebugInfo() {
+        return mDebugInfo == null
+                ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+    }
+
+    /**
+     * Associates information with the instance that can be useful for debugging / logging.
+     *
+     * <p>See {@link TimeSuggestionHelper} for more information about {@code debugInfo}.
+     */
+    public void addDebugInfo(@NonNull String debugInfo) {
+        if (mDebugInfo == null) {
+            mDebugInfo = new ArrayList<>();
+        }
+        mDebugInfo.add(debugInfo);
+    }
+
+    /**
+     * Associates information with the instance that can be useful for debugging / logging. The
+     * information is present in {@link #toString()} but is not considered for
+     * {@link #equals(Object)} and {@link #hashCode()}.
+     */
+    public void addDebugInfo(String... debugInfos) {
+        addDebugInfo(Arrays.asList(debugInfos));
+    }
+
+    /**
+     * Associates information with the instance that can be useful for debugging / logging.
+     *
+     * <p>See {@link TimeSuggestionHelper} for more information about {@code debugInfo}.
+     */
+    public void addDebugInfo(@NonNull List<String> debugInfo) {
+        if (mDebugInfo == null) {
+            mDebugInfo = new ArrayList<>(debugInfo.size());
+        }
+        mDebugInfo.addAll(debugInfo);
+    }
+
+    /**
+     * Implemented in case users call this insteam of {@link #handleEquals(TimeSuggestionHelper)}.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        TimeSuggestionHelper that = (TimeSuggestionHelper) o;
+        return handleEquals(that);
+    }
+
+    /** Used to implement {@link Object#equals(Object)}. */
+    public boolean handleEquals(TimeSuggestionHelper o) {
+        return Objects.equals(mHelpedClass, o.mHelpedClass)
+                && Objects.equals(mUnixEpochTime, o.mUnixEpochTime);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mUnixEpochTime);
+    }
+
+    /** Used to implement {@link Object#toString()}. */
+    public String handleToString() {
+        return mHelpedClass.getSimpleName() + "{"
+                + "mUnixEpochTime=" + mUnixEpochTime
+                + ", mDebugInfo=" + mDebugInfo
+                + '}';
+    }
+
+    /** Constructs a helper with suggestion state from a Parcel. */
+    public static TimeSuggestionHelper handleCreateFromParcel(@NonNull Class<?> helpedClass,
+            @NonNull Parcel in) {
+        @SuppressWarnings("unchecked")
+        TimestampedValue<Long> unixEpochTime = in.readParcelable(
+                null /* classLoader */, TimestampedValue.class);
+        TimeSuggestionHelper suggestionHelper =
+                new TimeSuggestionHelper(helpedClass, unixEpochTime);
+        suggestionHelper.mDebugInfo = in.readArrayList(null /* classLoader */, String.class);
+        return suggestionHelper;
+    }
+
+    /** Writes the helper suggestion state to a Parcel. */
+    public void handleWriteToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mUnixEpochTime, 0);
+        dest.writeList(mDebugInfo);
+    }
+
+    /** Parses command line args to create a {@link TimeSuggestionHelper}. */
+    public static TimeSuggestionHelper handleParseCommandLineArg(
+            @NonNull Class<?> helpedClass, @NonNull ShellCommand cmd)
+            throws IllegalArgumentException {
+        Long referenceTimeMillis = null;
+        Long unixEpochTimeMillis = null;
+        String opt;
+        while ((opt = cmd.getNextArg()) != null) {
+            switch (opt) {
+                case "--reference_time": {
+                    referenceTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                case "--unix_epoch_time": {
+                    unixEpochTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException("Unknown option: " + opt);
+                }
+            }
+        }
+
+        if (referenceTimeMillis == null) {
+            throw new IllegalArgumentException("No referenceTimeMillis specified.");
+        }
+        if (unixEpochTimeMillis == null) {
+            throw new IllegalArgumentException("No unixEpochTimeMillis specified.");
+        }
+
+        TimestampedValue<Long> timeSignal =
+                new TimestampedValue<>(referenceTimeMillis, unixEpochTimeMillis);
+        TimeSuggestionHelper suggestionHelper = new TimeSuggestionHelper(helpedClass, timeSignal);
+        suggestionHelper.addDebugInfo("Command line injection");
+        return suggestionHelper;
+    }
+
+    /** Prints the command line args needed to create a {@link TimeSuggestionHelper}. */
+    public static void handlePrintCommandLineOpts(
+            @NonNull PrintWriter pw, @NonNull String typeName, @NonNull Class<?> clazz) {
+        pw.printf("%s suggestion options:\n", typeName);
+        pw.println("  --reference_time <elapsed realtime millis>");
+        pw.println("  --unix_epoch_time <Unix epoch time millis>");
+        pw.println();
+        pw.println("See " + clazz.getName() + " for more information");
+    }
+}
diff --git a/core/java/android/appwidget/OWNERS b/core/java/android/appwidget/OWNERS
index 439df4b..554b0de 100644
--- a/core/java/android/appwidget/OWNERS
+++ b/core/java/android/appwidget/OWNERS
@@ -1,3 +1,4 @@
 pinyaoting@google.com
+sihua@google.com
 suprabh@google.com
 sunnygoyal@google.com
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index f72288c..9a7a949 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -55,4 +55,5 @@
     int getParentSessionId();
 
     boolean isStaged();
+    int getInstallFlags();
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3f8aedb..4030708 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1432,6 +1432,18 @@
         }
 
         /**
+         * @return Session's {@link SessionParams#installFlags}.
+         * @hide
+         */
+        public int getInstallFlags() {
+            try {
+                return mSession.getInstallFlags();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
          * @return the session ID of the multi-package session that this belongs to or
          * {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session.
          */
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5119010..ce21214 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2929,6 +2929,8 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device has a CDMA telephony stack.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY} has been defined.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
@@ -2936,6 +2938,8 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device has a GSM telephony stack.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY} has been defined.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
@@ -2947,6 +2951,9 @@
      * <p>Devices declaring this feature must have an implementation of the
      * {@link android.telephony.TelephonyManager#getAllowedCarriers} and
      * {@link android.telephony.TelephonyManager#setAllowedCarriers}.
+     *
+     * This feature should only be defined if {@link #FEATURE_TELEPHONY_SUBSCRIPTION}
+     * has been defined.
      * @hide
      */
     @SystemApi
@@ -2957,6 +2964,9 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
      * supports embedded subscriptions on eUICCs.
+     *
+     * This feature should only be defined if {@link #FEATURE_TELEPHONY_SUBSCRIPTION}
+     * has been defined.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
@@ -2964,6 +2974,9 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
      * supports cell-broadcast reception using the MBMS APIs.
+     *
+     * <p>This feature should only be defined if both {@link #FEATURE_TELEPHONY_SUBSCRIPTION}
+     * and {@link #FEATURE_TELEPHONY_RADIO_ACCESS} have been defined.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_MBMS = "android.hardware.telephony.mbms";
@@ -2971,6 +2984,8 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
      * supports attaching to IMS implementations using the ImsService API in telephony.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY_DATA} has been defined.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
@@ -3007,6 +3022,62 @@
             "android.hardware.telephony.ims.singlereg";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telecom Service APIs.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELECOM = "android.software.telecom";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telephony APIs for calling service.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY_RADIO_ACCESS},
+     * {@link #FEATURE_TELEPHONY_SUBSCRIPTION}, and {@link #FEATURE_TELECOM} have been defined.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telephony APIs for data service.
+     *
+     * <p>This feature should only be defined if both {@link #FEATURE_TELEPHONY_SUBSCRIPTION}
+     * and {@link #FEATURE_TELEPHONY_RADIO_ACCESS} have been defined.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_DATA = "android.hardware.telephony.data";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telephony APIs for SMS and MMS.
+     *
+     * <p>This feature should only be defined if both {@link #FEATURE_TELEPHONY_SUBSCRIPTION}
+     * and {@link #FEATURE_TELEPHONY_RADIO_ACCESS} have been defined.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_MESSAGING = "android.hardware.telephony.messaging";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telephony APIs for the radio access.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY} has been defined.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_RADIO_ACCESS = "android.hardware.telephony.radio";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device supports Telephony APIs for the subscription.
+     *
+     * <p>This feature should only be defined if {@link #FEATURE_TELEPHONY} has been defined.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TELEPHONY_SUBSCRIPTION =
+            "android.hardware.telephony.subscription";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device is capable of communicating with
      * other devices via ultra wideband.
@@ -3047,7 +3118,9 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The Connection Service API is enabled on the device.
+     * @deprecated use {@link #FEATURE_TELECOM} instead.
      */
+    @Deprecated
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
 
diff --git a/core/java/android/hardware/input/OWNERS b/core/java/android/hardware/input/OWNERS
index c390b33..4c20c4d 100644
--- a/core/java/android/hardware/input/OWNERS
+++ b/core/java/android/hardware/input/OWNERS
@@ -1,3 +1 @@
-# Bug component: 136048
-
-include /services/core/java/com/android/server/input/OWNERS
+include /INPUT_OWNERS
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 7f07af7..3e79f18 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -18,6 +18,7 @@
 
 import android.app.PendingIntent;
 import android.content.ComponentName;
+import android.hardware.usb.IUsbOperationInternal;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.ParcelableUsbPort;
@@ -136,7 +137,7 @@
     void resetUsbGadget();
 
     /* Set USB data on or off */
-    boolean enableUsbDataSignal(boolean enable);
+    boolean enableUsbData(in String portId, boolean enable, int operationId, in IUsbOperationInternal callback);
 
     /* Gets the USB Hal Version. */
     int getUsbHalVersion();
@@ -159,6 +160,6 @@
     /* Enable/disable contaminant detection */
     void enableContaminantDetection(in String portId, boolean enable);
 
-   /* Sets USB device connection handler. */
-   void setUsbDeviceConnectionHandler(in ComponentName usbDeviceConnectionHandler);
+    /* Sets USB device connection handler. */
+    void setUsbDeviceConnectionHandler(in ComponentName usbDeviceConnectionHandler);
 }
diff --git a/core/java/android/hardware/usb/IUsbOperationInternal.aidl b/core/java/android/hardware/usb/IUsbOperationInternal.aidl
new file mode 100644
index 0000000..3f3bbf6
--- /dev/null
+++ b/core/java/android/hardware/usb/IUsbOperationInternal.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+/**
+ * @hide
+ */
+oneway interface IUsbOperationInternal {
+void onOperationComplete(in int status);
+}
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 964d7c1..df70bfd 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -36,6 +36,8 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.hardware.usb.gadget.V1_0.GadgetFunction;
 import android.hardware.usb.gadget.V1_2.UsbSpeed;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbPort;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -48,6 +50,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -516,6 +519,14 @@
     public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024;
 
     /**
+     * Returned when the client has to retry querying the version.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_RETRY = -2;
+
+    /**
      * The Value for USB hal is not presented.
      *
      * {@hide}
@@ -556,6 +567,14 @@
     public static final int USB_HAL_V1_3 = 13;
 
     /**
+     * Value for USB Hal Version v2.0.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int USB_HAL_V2_0 = 20;
+
+    /**
      * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
      * {@hide}
      */
@@ -664,6 +683,7 @@
             USB_HAL_V1_1,
             USB_HAL_V1_2,
             USB_HAL_V1_3,
+            USB_HAL_V2_0,
     })
     public @interface UsbHalVersion {}
 
@@ -1168,8 +1188,9 @@
     /**
      * Enable/Disable the USB data signaling.
      * <p>
-     * Enables/Disables USB data path in all the USB ports.
+     * Enables/Disables USB data path of the first port..
      * It will force to stop or restore USB data signaling.
+     * Call UsbPort API if the device has more than one UsbPort.
      * </p>
      *
      * @param enable enable or disable USB data signaling
@@ -1180,11 +1201,11 @@
      */
     @RequiresPermission(Manifest.permission.MANAGE_USB)
     public boolean enableUsbDataSignal(boolean enable) {
-        try {
-            return mService.enableUsbDataSignal(enable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        List<UsbPort> usbPorts = getPorts();
+        if (usbPorts.size() == 1) {
+            return usbPorts.get(0).enableUsbData(enable) == UsbPort.ENABLE_USB_DATA_SUCCESS;
         }
+        return false;
     }
 
     /**
@@ -1270,6 +1291,41 @@
     }
 
     /**
+     * Should only be called by {@link UsbPort#enableUsbData}.
+     * <p>
+     * Enables or disables USB data on the specific port.
+     *
+     * @param port USB port for which USB data needs to be enabled or disabled.
+     * @param enable Enable USB data when true.
+     *               Disable USB data when false.
+     * @param operationId operationId for the request.
+     * @param callback callback object to be invoked when the operation is complete.
+     * @return True when the operation is asynchronous. The caller must therefore call
+     *         {@link UsbOperationInternal#waitForOperationComplete} for processing
+     *         the result.
+     *         False when the operation is synchronous. Caller can proceed reading the result
+     *         through {@link UsbOperationInternal#getStatus}
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    boolean enableUsbData(@NonNull UsbPort port, boolean enable, int operationId,
+            IUsbOperationInternal callback) {
+        Objects.requireNonNull(port, "enableUsbData: port must not be null. opId:" + operationId);
+        try {
+            return mService.enableUsbData(port.getId(), enable, operationId, callback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "enableUsbData: failed. opId:" + operationId, e);
+            try {
+                callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
+            } catch (RemoteException r) {
+                Log.e(TAG, "enableUsbData: failed to call onOperationComplete. opId:"
+                        + operationId, r);
+            }
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Sets the component that will handle USB device connection.
      * <p>
      * Setting component allows to specify external USB host manager to handle use cases, where
diff --git a/core/java/android/hardware/usb/UsbOperationInternal.java b/core/java/android/hardware/usb/UsbOperationInternal.java
new file mode 100644
index 0000000..9bc2b38
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbOperationInternal.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.usb;
+
+import android.annotation.IntDef;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbPort;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.TimeUnit;
+/**
+ * UsbOperationInternal allows UsbPort to support both synchronous and
+ * asynchronous function irrespective of whether the underlying hal
+ * method is synchronous or asynchronous.
+ *
+ * @hide
+ */
+public final class UsbOperationInternal extends IUsbOperationInternal.Stub {
+    private static final String TAG = "UsbPortStatus";
+    private final int mOperationID;
+    // Cached portId.
+    private final String mId;
+    // True implies operation did not timeout.
+    private boolean mOperationComplete;
+    private @UsbOperationStatus int mStatus;
+    final ReentrantLock mLock = new ReentrantLock();
+    final Condition mOperationWait  = mLock.newCondition();
+    // Maximum time the caller has to wait for onOperationComplete to be called.
+    private static final int USB_OPERATION_TIMEOUT_MSECS = 5000;
+
+    /**
+     * The requested operation was successfully completed.
+     * Returned in {@link onOperationComplete} and {@link getStatus}.
+     */
+    public static final int USB_OPERATION_SUCCESS = 0;
+
+    /**
+     * The requested operation failed due to internal error.
+     * Returned in {@link onOperationComplete} and {@link getStatus}.
+     */
+    public static final int USB_OPERATION_ERROR_INTERNAL = 1;
+
+    /**
+     * The requested operation failed as it's not supported.
+     * Returned in {@link onOperationComplete} and {@link getStatus}.
+     */
+    public static final int USB_OPERATION_ERROR_NOT_SUPPORTED = 2;
+
+    /**
+     * The requested operation failed as it's not supported.
+     * Returned in {@link onOperationComplete} and {@link getStatus}.
+     */
+    public static final int USB_OPERATION_ERROR_PORT_MISMATCH = 3;
+
+    @IntDef(prefix = { "USB_OPERATION_" }, value = {
+            USB_OPERATION_SUCCESS,
+            USB_OPERATION_ERROR_INTERNAL,
+            USB_OPERATION_ERROR_NOT_SUPPORTED,
+            USB_OPERATION_ERROR_PORT_MISMATCH
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface UsbOperationStatus{}
+
+    UsbOperationInternal(int operationID, String id) {
+        this.mOperationID = operationID;
+        this.mId = id;
+    }
+
+    /**
+     * Hal glue layer would directly call this function when the requested
+     * operation is complete.
+     */
+    @Override
+    public void onOperationComplete(@UsbOperationStatus int status) {
+        mLock.lock();
+        try {
+            mOperationComplete = true;
+            mStatus = status;
+            Log.i(TAG, "Port:" + mId + " opID:" + mOperationID + " status:" + mStatus);
+            mOperationWait.signal();
+        } finally {
+            mLock.unlock();
+        }
+    }
+
+    /**
+     * Caller invokes this function to wait for the operation to be complete.
+     */
+    public void waitForOperationComplete() {
+        mLock.lock();
+        try {
+            long now = System.currentTimeMillis();
+            long deadline = now + USB_OPERATION_TIMEOUT_MSECS;
+            // Wait in loop to overcome spurious wakeups.
+            do {
+                mOperationWait.await(deadline - System.currentTimeMillis(),
+                        TimeUnit.MILLISECONDS);
+            } while (!mOperationComplete && System.currentTimeMillis() < deadline);
+            if (!mOperationComplete) {
+                Log.e(TAG, "Port:" + mId + " opID:" + mOperationID
+                        + " operationComplete not received in " + USB_OPERATION_TIMEOUT_MSECS
+                        + "msecs");
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Port:" + mId + " opID:" + mOperationID + " operationComplete interrupted");
+        } finally {
+            mLock.unlock();
+        }
+    }
+
+    public @UsbOperationStatus int getStatus() {
+        return mOperationComplete ? mStatus : USB_OPERATION_ERROR_INTERNAL;
+    }
+}
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index 274e23f..f469a3e 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -16,6 +16,10 @@
 
 package android.hardware.usb;
 
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_NOT_SUPPORTED;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_PORT_MISMATCH;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_SUCCESS;
 import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_DETECTED;
 import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_DISABLED;
 import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED;
@@ -34,15 +38,23 @@
 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
 
 import android.Manifest;
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.hardware.usb.UsbOperationInternal;
 import android.hardware.usb.V1_0.Constants;
+import android.os.Binder;
+import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Represents a physical USB port and describes its characteristics.
@@ -51,6 +63,7 @@
  */
 @SystemApi
 public final class UsbPort {
+    private static final String TAG = "UsbPort";
     private final String mId;
     private final int mSupportedModes;
     private final UsbManager mUsbManager;
@@ -64,6 +77,47 @@
      */
     private static final int POWER_ROLE_OFFSET = Constants.PortPowerRole.NONE;
 
+    /**
+     * Counter for tracking UsbOperation operations.
+     */
+    private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
+    /**
+     * The {@link #enableUsbData} request was successfully completed.
+     */
+    public static final int ENABLE_USB_DATA_SUCCESS = 0;
+
+    /**
+     * The {@link #enableUsbData} request failed due to internal error.
+     */
+    public static final int ENABLE_USB_DATA_ERROR_INTERNAL = 1;
+
+    /**
+     * The {@link #enableUsbData} request failed as it's not supported.
+     */
+    public static final int ENABLE_USB_DATA_ERROR_NOT_SUPPORTED = 2;
+
+    /**
+     * The {@link #enableUsbData} request failed as port id mismatched.
+     */
+    public static final int ENABLE_USB_DATA_ERROR_PORT_MISMATCH = 3;
+
+    /**
+     * The {@link #enableUsbData} request failed due to other reasons.
+     */
+    public static final int ENABLE_USB_DATA_ERROR_OTHER = 4;
+
+    /** @hide */
+    @IntDef(prefix = { "ENABLE_USB_DATA_" }, value = {
+            ENABLE_USB_DATA_SUCCESS,
+            ENABLE_USB_DATA_ERROR_INTERNAL,
+            ENABLE_USB_DATA_ERROR_NOT_SUPPORTED,
+            ENABLE_USB_DATA_ERROR_PORT_MISMATCH,
+            ENABLE_USB_DATA_ERROR_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface EnableUsbDataStatus{}
+
     /** @hide */
     public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes,
             int supportedContaminantProtectionModes,
@@ -157,7 +211,7 @@
      * {@link UsbPortStatus#isRoleCombinationSupported UsbPortStatus.isRoleCombinationSupported}.
      * </p><p>
      * Note: This function is asynchronous and may fail silently without applying
-     * the requested changes.  If this function does cause a status change to occur then
+     * the operationed changes.  If this function does cause a status change to occur then
      * a {@link UsbManager#ACTION_USB_PORT_CHANGED} broadcast will be sent.
      * </p>
      *
@@ -177,6 +231,47 @@
     }
 
     /**
+     * Enables/Disables Usb data on the port.
+     *
+     * @param enable When true enables USB data if disabled.
+     *               When false disables USB data if enabled.
+     * @return       {@link #ENABLE_USB_DATA_SUCCESS} when request completes successfully or
+     *               {@link #ENABLE_USB_DATA_ERROR_INTERNAL} when request fails due to internal
+     *               error or
+     *               {@link ENABLE_USB_DATA_ERROR_NOT_SUPPORTED} when not supported or
+     *               {@link ENABLE_USB_DATA_ERROR_PORT_MISMATCH} when request fails due to port id
+     *               mismatch or
+     *               {@link ENABLE_USB_DATA_ERROR_OTHER} when fails due to other reasons.
+     */
+    @CheckResult
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    public @EnableUsbDataStatus int enableUsbData(boolean enable) {
+        // UID is added To minimize operationID overlap between two different packages.
+        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
+        Log.i(TAG, "enableUsbData opId:" + operationId
+                + " callingUid:" + Binder.getCallingUid());
+        UsbOperationInternal opCallback =
+                new UsbOperationInternal(operationId, mId);
+        if (mUsbManager.enableUsbData(this, enable, operationId, opCallback) == true) {
+            opCallback.waitForOperationComplete();
+        }
+
+        int result = opCallback.getStatus();
+        switch (result) {
+            case USB_OPERATION_SUCCESS:
+                return ENABLE_USB_DATA_SUCCESS;
+            case USB_OPERATION_ERROR_INTERNAL:
+                return ENABLE_USB_DATA_ERROR_INTERNAL;
+            case USB_OPERATION_ERROR_NOT_SUPPORTED:
+                return ENABLE_USB_DATA_ERROR_NOT_SUPPORTED;
+            case USB_OPERATION_ERROR_PORT_MISMATCH:
+                return ENABLE_USB_DATA_ERROR_PORT_MISMATCH;
+            default:
+                return ENABLE_USB_DATA_ERROR_OTHER;
+        }
+    }
+
+    /**
      * @hide
      **/
     public void enableContaminantDetection(boolean enable) {
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index bb7aff6..bd2f9aa 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -19,7 +19,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
-import android.hardware.usb.V1_0.Constants;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -36,27 +35,29 @@
 @Immutable
 @SystemApi
 public final class UsbPortStatus implements Parcelable {
+    private static final String TAG = "UsbPortStatus";
     private final int mCurrentMode;
     private final @UsbPowerRole int mCurrentPowerRole;
     private final @UsbDataRole int mCurrentDataRole;
     private final int mSupportedRoleCombinations;
     private final @ContaminantProtectionStatus int mContaminantProtectionStatus;
     private final @ContaminantDetectionStatus int mContaminantDetectionStatus;
+    private final boolean mUsbDataEnabled;
 
     /**
      * Power role: This USB port does not have a power role.
      */
-    public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE;
+    public static final int POWER_ROLE_NONE = 0;
 
     /**
      * Power role: This USB port can act as a source (provide power).
      */
-    public static final int POWER_ROLE_SOURCE = Constants.PortPowerRole.SOURCE;
+    public static final int POWER_ROLE_SOURCE = 1;
 
     /**
      * Power role: This USB port can act as a sink (receive power).
      */
-    public static final int POWER_ROLE_SINK = Constants.PortPowerRole.SINK;
+    public static final int POWER_ROLE_SINK = 2;
 
     @IntDef(prefix = { "POWER_ROLE_" }, value = {
             POWER_ROLE_NONE,
@@ -69,17 +70,17 @@
     /**
      * Power role: This USB port does not have a data role.
      */
-    public static final int DATA_ROLE_NONE = Constants.PortDataRole.NONE;
+    public static final int DATA_ROLE_NONE = 0;
 
     /**
      * Data role: This USB port can act as a host (access data services).
      */
-    public static final int DATA_ROLE_HOST = Constants.PortDataRole.HOST;
+    public static final int DATA_ROLE_HOST = 1;
 
     /**
      * Data role: This USB port can act as a device (offer data services).
      */
-    public static final int DATA_ROLE_DEVICE = Constants.PortDataRole.DEVICE;
+    public static final int DATA_ROLE_DEVICE = 2;
 
     @IntDef(prefix = { "DATA_ROLE_" }, value = {
             DATA_ROLE_NONE,
@@ -92,15 +93,7 @@
     /**
      * There is currently nothing connected to this USB port.
      */
-    public static final int MODE_NONE = Constants.PortMode.NONE;
-
-    /**
-     * This USB port can act as a downstream facing port (host).
-     *
-     * <p> Implies that the port supports the {@link #POWER_ROLE_SOURCE} and
-     * {@link #DATA_ROLE_HOST} combination of roles (and possibly others as well).
-     */
-    public static final int MODE_DFP = Constants.PortMode.DFP;
+    public static final int MODE_NONE = 0;
 
     /**
      * This USB port can act as an upstream facing port (device).
@@ -108,7 +101,15 @@
      * <p> Implies that the port supports the {@link #POWER_ROLE_SINK} and
      * {@link #DATA_ROLE_DEVICE} combination of roles (and possibly others as well).
      */
-    public static final int MODE_UFP = Constants.PortMode.UFP;
+    public static final int MODE_UFP = 1 << 0;
+
+    /**
+     * This USB port can act as a downstream facing port (host).
+     *
+     * <p> Implies that the port supports the {@link #POWER_ROLE_SOURCE} and
+     * {@link #DATA_ROLE_HOST} combination of roles (and possibly others as well).
+     */
+    public static final int MODE_DFP = 1 << 1;
 
     /**
      * This USB port can act either as an downstream facing port (host) or as
@@ -120,87 +121,76 @@
      *
      * @hide
      */
-    public static final int MODE_DUAL = Constants.PortMode.DRP;
+    public static final int MODE_DUAL = MODE_UFP | MODE_DFP;
 
     /**
      * This USB port can support USB Type-C Audio accessory.
      */
-    public static final int MODE_AUDIO_ACCESSORY =
-            android.hardware.usb.V1_1.Constants.PortMode_1_1.AUDIO_ACCESSORY;
+    public static final int MODE_AUDIO_ACCESSORY = 1 << 2;
 
     /**
      * This USB port can support USB Type-C debug accessory.
      */
-    public static final int MODE_DEBUG_ACCESSORY =
-            android.hardware.usb.V1_1.Constants.PortMode_1_1.DEBUG_ACCESSORY;
+    public static final int MODE_DEBUG_ACCESSORY = 1 << 3;
 
    /**
      * Contaminant presence detection not supported by the device.
      * @hide
      */
-    public static final int CONTAMINANT_DETECTION_NOT_SUPPORTED =
-            android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.NOT_SUPPORTED;
+    public static final int CONTAMINANT_DETECTION_NOT_SUPPORTED = 0;
 
     /**
      * Contaminant presence detection supported but disabled.
      * @hide
      */
-    public static final int CONTAMINANT_DETECTION_DISABLED =
-            android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.DISABLED;
+    public static final int CONTAMINANT_DETECTION_DISABLED = 1;
 
     /**
      * Contaminant presence enabled but not detected.
      * @hide
      */
-    public static final int CONTAMINANT_DETECTION_NOT_DETECTED =
-            android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.NOT_DETECTED;
+    public static final int CONTAMINANT_DETECTION_NOT_DETECTED = 2;
 
     /**
      * Contaminant presence enabled and detected.
      * @hide
      */
-    public static final int CONTAMINANT_DETECTION_DETECTED =
-            android.hardware.usb.V1_2.Constants.ContaminantDetectionStatus.DETECTED;
+    public static final int CONTAMINANT_DETECTION_DETECTED = 3;
 
     /**
      * Contaminant protection - No action performed upon detection of
      * contaminant presence.
      * @hide
      */
-    public static final int CONTAMINANT_PROTECTION_NONE =
-            android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.NONE;
+    public static final int CONTAMINANT_PROTECTION_NONE = 0;
 
     /**
      * Contaminant protection - Port is forced to sink upon detection of
      * contaminant presence.
      * @hide
      */
-    public static final int CONTAMINANT_PROTECTION_SINK =
-            android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_SINK;
+    public static final int CONTAMINANT_PROTECTION_SINK = 1 << 0;
 
     /**
      * Contaminant protection - Port is forced to source upon detection of
      * contaminant presence.
      * @hide
      */
-    public static final int CONTAMINANT_PROTECTION_SOURCE =
-            android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_SOURCE;
+    public static final int CONTAMINANT_PROTECTION_SOURCE = 1 << 1;
 
     /**
      * Contaminant protection - Port is disabled upon detection of
      * contaminant presence.
      * @hide
      */
-    public static final int CONTAMINANT_PROTECTION_FORCE_DISABLE =
-            android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.FORCE_DISABLE;
+    public static final int CONTAMINANT_PROTECTION_FORCE_DISABLE = 1 << 2;
 
     /**
      * Contaminant protection - Port is disabled upon detection of
      * contaminant presence.
      * @hide
      */
-    public static final int CONTAMINANT_PROTECTION_DISABLED =
-            android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.DISABLED;
+    public static final int CONTAMINANT_PROTECTION_DISABLED = 1 << 3;
 
     @IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = {
             CONTAMINANT_DETECTION_NOT_SUPPORTED,
@@ -234,6 +224,19 @@
     /** @hide */
     public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
             int supportedRoleCombinations, int contaminantProtectionStatus,
+            int contaminantDetectionStatus, boolean usbDataEnabled) {
+        mCurrentMode = currentMode;
+        mCurrentPowerRole = currentPowerRole;
+        mCurrentDataRole = currentDataRole;
+        mSupportedRoleCombinations = supportedRoleCombinations;
+        mContaminantProtectionStatus = contaminantProtectionStatus;
+        mContaminantDetectionStatus = contaminantDetectionStatus;
+        mUsbDataEnabled = usbDataEnabled;
+    }
+
+    /** @hide */
+    public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
+            int supportedRoleCombinations, int contaminantProtectionStatus,
             int contaminantDetectionStatus) {
         mCurrentMode = currentMode;
         mCurrentPowerRole = currentPowerRole;
@@ -241,6 +244,7 @@
         mSupportedRoleCombinations = supportedRoleCombinations;
         mContaminantProtectionStatus = contaminantProtectionStatus;
         mContaminantDetectionStatus = contaminantDetectionStatus;
+        mUsbDataEnabled = true;
     }
 
     /**
@@ -323,6 +327,15 @@
         return mContaminantProtectionStatus;
     }
 
+    /**
+     * Returns UsbData status.
+     *
+     * @hide
+     */
+    public boolean getUsbDataStatus() {
+        return mUsbDataEnabled;
+    }
+
     @NonNull
     @Override
     public String toString() {
@@ -336,6 +349,8 @@
                         + getContaminantDetectionStatus()
                 + ", contaminantProtectionStatus="
                         + getContaminantProtectionStatus()
+                + ", usbDataEnabled="
+                        + getUsbDataStatus()
                 + "}";
     }
 
@@ -352,6 +367,7 @@
         dest.writeInt(mSupportedRoleCombinations);
         dest.writeInt(mContaminantProtectionStatus);
         dest.writeInt(mContaminantDetectionStatus);
+        dest.writeBoolean(mUsbDataEnabled);
     }
 
     public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
@@ -364,9 +380,10 @@
             int supportedRoleCombinations = in.readInt();
             int contaminantProtectionStatus = in.readInt();
             int contaminantDetectionStatus = in.readInt();
+            boolean usbDataEnabled = in.readBoolean();
             return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                     supportedRoleCombinations, contaminantProtectionStatus,
-                    contaminantDetectionStatus);
+                    contaminantDetectionStatus, usbDataEnabled);
         }
 
         @Override
diff --git a/core/java/android/net/IVpnManager.aidl b/core/java/android/net/IVpnManager.aidl
index b4647ca..f302378 100644
--- a/core/java/android/net/IVpnManager.aidl
+++ b/core/java/android/net/IVpnManager.aidl
@@ -42,6 +42,8 @@
     String startVpnProfile(String packageName);
     void stopVpnProfile(String packageName);
     VpnProfileState getProvisionedVpnProfileState(String packageName);
+    boolean setAppExclusionList(int userId, String vpnPackage, in List<String> excludedApps);
+    List<String> getAppExclusionList(int userId, String vpnPackage);
 
     /** Always-on VPN APIs */
     boolean isAlwaysOnVpnPackageSupported(int userId, String packageName);
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index ae7d91f..f62d7c4 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -187,14 +187,24 @@
     /**
      * The network that was underlying the VPN when the event occurred, as a {@link Network}.
      *
-     * This extra will be null if there was no underlying network at the time of the event.
+     * <p>This extra will be null if there was no underlying network at the time of the event, or
+     *    the underlying network has no bearing on the event, as in the case of:
+     * <ul>
+     *   <li>CATEGORY_EVENT_DEACTIVATED_BY_USER
+     *   <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED
+     * </ul>
      */
     public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK";
 
     /**
      * The {@link NetworkCapabilities} of the underlying network when the event occurred.
      *
-     * This extra will be null if there was no underlying network at the time of the event.
+     * <p>This extra will be null if there was no underlying network at the time of the event, or
+     *    the underlying network has no bearing on the event, as in the case of:
+     * <ul>
+     *   <li>CATEGORY_EVENT_DEACTIVATED_BY_USER
+     *   <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED
+     * </ul>
      */
     public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES =
             "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES";
@@ -202,7 +212,12 @@
     /**
      * The {@link LinkProperties} of the underlying network when the event occurred.
      *
-     * This extra will be null if there was no underlying network at the time of the event.
+     * <p>This extra will be null if there was no underlying network at the time of the event, or
+     *    the underlying network has no bearing on the event, as in the case of:
+     * <ul>
+     *   <li>CATEGORY_EVENT_DEACTIVATED_BY_USER
+     *   <li>CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED
+     * </ul>
      */
     public static final String EXTRA_UNDERLYING_LINK_PROPERTIES =
             "android.net.extra.UNDERLYING_LINK_PROPERTIES";
@@ -580,6 +595,63 @@
     }
 
     /**
+     * Sets the application exclusion list for the specified VPN profile.
+     *
+     * <p>If an app in the set of excluded apps is not installed for the given user, it will be
+     * skipped in the list of app exclusions. If apps are installed or removed, any active VPN will
+     * have its UID set updated automatically. If the caller is not {@code userId},
+     * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
+     *
+     * <p>This will ONLY affect VpnManager profiles. As such, the NETWORK_SETTINGS provider MUST NOT
+     * allow configuration of these options if the application has not provided a VPN profile.
+     *
+     * @param userId the identifier of the user to set app exclusion list
+     * @param vpnPackage The package name for an installed VPN app on the device
+     * @param excludedApps the app exclusion list
+     * @throws IllegalStateException exception if vpn for the @code userId} is not ready yet.
+     *
+     * @return whether setting the list is successful or not
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    public boolean setAppExclusionList(int userId, @NonNull String vpnPackage,
+            @NonNull List<String> excludedApps) {
+        try {
+            return mService.setAppExclusionList(userId, vpnPackage, excludedApps);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the application exclusion list for the specified VPN profile. If the caller is not
+     * {@code userId}, {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission
+     * is required.
+     *
+     * @param userId the identifier of the user to set app exclusion list
+     * @param vpnPackage The package name for an installed VPN app on the device
+     * @return the list of packages for the specified VPN profile or null if no corresponding VPN
+     *         profile configured.
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
+    @Nullable
+    public List<String> getAppExclusionList(int userId, @NonNull String vpnPackage) {
+        try {
+            return mService.getAppExclusionList(userId, vpnPackage);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @return the list of packages that are allowed to access network when always-on VPN is in
      * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
      *
diff --git a/core/java/android/net/VpnProfileState.java b/core/java/android/net/VpnProfileState.java
index c69ea1a..552a2c1 100644
--- a/core/java/android/net/VpnProfileState.java
+++ b/core/java/android/net/VpnProfileState.java
@@ -24,6 +24,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+import java.util.StringJoiner;
 
 /**
  * Describe the state of VPN.
@@ -150,4 +152,44 @@
         mAlwaysOn = in.readBoolean();
         mLockdown = in.readBoolean();
     }
+
+    private String convertStateToString(@State int state) {
+        switch (state) {
+            case STATE_CONNECTED:
+                return "CONNECTED";
+            case STATE_CONNECTING:
+                return "CONNECTING";
+            case STATE_DISCONNECTED:
+                return "DISCONNECTED";
+            case STATE_FAILED:
+                return "FAILED";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    @Override
+    public String toString() {
+        final StringJoiner resultJoiner = new StringJoiner(", ", "{", "}");
+        resultJoiner.add("State: " + convertStateToString(getState()));
+        resultJoiner.add("SessionId: " + getSessionId());
+        resultJoiner.add("Always-on: " + isAlwaysOn());
+        resultJoiner.add("Lockdown: " + isLockdownEnabled());
+        return resultJoiner.toString();
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof VpnProfileState)) return false;
+        final VpnProfileState that = (VpnProfileState) obj;
+        return (getState() == that.getState()
+                && Objects.equals(getSessionId(), that.getSessionId())
+                && isAlwaysOn() == that.isAlwaysOn()
+                && isLockdownEnabled() == that.isLockdownEnabled());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getState(), getSessionId(), isAlwaysOn(), isLockdownEnabled());
+    }
 }
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index f1b110a..40e4083 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -104,6 +104,14 @@
 
     // TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz
 
+    /** List of Carrier Config options to extract from Carrier Config bundles. @hide */
+    @NonNull
+    public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
+            new String[] {
+                VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
+                VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY
+            };
+
     private static final Map<
                     VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
             REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 45cc324d..141b141 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -406,7 +406,7 @@
         public static final String CODENAME = getString("ro.build.version.codename");
 
         /**
-         * All known codenames starting from {@link VERSION_CODES.Q}.
+         * All known codenames that are present in {@link VERSION_CODES}.
          *
          * <p>This includes in development codenames as well, i.e. if {@link #CODENAME} is not "REL"
          * then the value of that is present in this set.
@@ -1167,6 +1167,11 @@
          * Tiramisu.
          */
         public static final int TIRAMISU = CUR_DEVELOPMENT;
+
+        /**
+         * Upside Down Cake.
+         */
+        public static final int UPSIDE_DOWN_CAKE = CUR_DEVELOPMENT;
     }
 
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 9e47a70..90e4b17 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -311,9 +311,11 @@
         public void binderDied();
 
         /**
-         * @hide
+         * Interface for receiving a callback when the process hosting an IBinder
+         * has gone away.
+         * @param who The IBinder that has become invalid
          */
-        default void binderDied(IBinder who) {
+        default void binderDied(@NonNull IBinder who) {
             binderDied();
         }
     }
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
index b5466b6..49f4bf7 100644
--- a/core/java/android/permission/OWNERS
+++ b/core/java/android/permission/OWNERS
@@ -5,10 +5,14 @@
 ewol@google.com
 guojing@google.com
 jaysullivan@google.com
+kvakil@google.com
+mrulhania@google.com
+narayan@google.com
+ntmyren@google.com
 olekarg@google.com
 pyuli@google.com
-ntmyren@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+raphk@google.com
+rmacgregor@google.com
+sergeynv@google.com
 theianchen@google.com
 zhanghai@google.com
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 4c1cc97..71b5354 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -306,6 +306,13 @@
     public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
 
     /**
+     * Namespace for all Kernel Multi-Gen LRU feature.
+     *
+     * @hide
+     */
+    public static final String NAMESPACE_MGLRU_NATIVE = "mglru_native";
+
+    /**
      * Namespace for all netd related features.
      *
      * @hide
diff --git a/core/java/android/speech/OWNERS b/core/java/android/speech/OWNERS
index 32f4822..462d8be 100644
--- a/core/java/android/speech/OWNERS
+++ b/core/java/android/speech/OWNERS
@@ -1,3 +1,4 @@
 volnov@google.com
 eugeniom@google.com
 schfan@google.com
+andreaambu@google.com
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 80ffd40..c33c2ab 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2263,8 +2263,11 @@
     }
 
     /**
-     * {@link #getX(int)} for the first pointer index (may be an
-     * arbitrary pointer identifier).
+     * Equivalent to {@link #getX(int)} for pointer index 0 (regardless of the
+     * pointer identifier).
+     *
+     * @return The X coordinate of the first pointer index in the coordinate
+     *      space of the view that received this motion event.
      *
      * @see #AXIS_X
      */
@@ -2273,8 +2276,11 @@
     }
 
     /**
-     * {@link #getY(int)} for the first pointer index (may be an
-     * arbitrary pointer identifier).
+     * Equivalent to {@link #getY(int)} for pointer index 0 (regardless of the
+     * pointer identifier).
+     *
+     * @return The Y coordinate of the first pointer index in the coordinate
+     *      space of the view that received this motion event.
      *
      * @see #AXIS_Y
      */
@@ -2416,13 +2422,20 @@
     }
 
     /**
-     * Returns the X coordinate of this event for the given pointer
-     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
-     * identifier for this index).
-     * Whole numbers are pixels; the
-     * value may have a fraction for input devices that are sub-pixel precise.
-     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
-     * (the first pointer that is down) to {@link #getPointerCount()}-1.
+     * Returns the X coordinate of the pointer referenced by
+     * {@code pointerIndex} for this motion event. The coordinate is in the
+     * coordinate space of the view that received this motion event.
+     *
+     * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+     * pointer referenced by {@code pointerIndex}.
+     *
+     * @param pointerIndex Index of the pointer for which the X coordinate is
+     *      returned. May be a value in the range of 0 (the first pointer that
+     *      is down) to {@link #getPointerCount()} - 1.
+     * @return The X coordinate of the pointer referenced by
+     *      {@code pointerIndex} for this motion event. The unit is pixels. The
+     *      value may contain a fractional portion for devices that are subpixel
+     *      precise.
      *
      * @see #AXIS_X
      */
@@ -2431,13 +2444,20 @@
     }
 
     /**
-     * Returns the Y coordinate of this event for the given pointer
-     * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
-     * identifier for this index).
-     * Whole numbers are pixels; the
-     * value may have a fraction for input devices that are sub-pixel precise.
-     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
-     * (the first pointer that is down) to {@link #getPointerCount()}-1.
+     * Returns the Y coordinate of the pointer referenced by
+     * {@code pointerIndex} for this motion event. The coordinate is in the
+     * coordinate space of the view that received this motion event.
+     *
+     * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+     * pointer referenced by {@code pointerIndex}.
+     *
+     * @param pointerIndex Index of the pointer for which the Y coordinate is
+     *      returned. May be a value in the range of 0 (the first pointer that
+     *      is down) to {@link #getPointerCount()} - 1.
+     * @return The Y coordinate of the pointer referenced by
+     *      {@code pointerIndex} for this motion event. The unit is pixels. The
+     *      value may contain a fractional portion for devices that are subpixel
+     *      precise.
      *
      * @see #AXIS_Y
      */
@@ -2683,12 +2703,13 @@
     }
 
     /**
-     * Returns the original raw X coordinate of this event.  For touch
-     * events on the screen, this is the original location of the event
-     * on the screen, before it had been adjusted for the containing window
-     * and views.
+     * Equivalent to {@link #getRawX(int)} for pointer index 0 (regardless of
+     * the pointer identifier).
      *
-     * @see #getX(int)
+     * @return The X coordinate of the first pointer index in the coordinate
+     *      space of the device display.
+     *
+     * @see #getX()
      * @see #AXIS_X
      */
     public final float getRawX() {
@@ -2696,12 +2717,13 @@
     }
 
     /**
-     * Returns the original raw Y coordinate of this event.  For touch
-     * events on the screen, this is the original location of the event
-     * on the screen, before it had been adjusted for the containing window
-     * and views.
+     * Equivalent to {@link #getRawY(int)} for pointer index 0 (regardless of
+     * the pointer identifier).
      *
-     * @see #getY(int)
+     * @return The Y coordinate of the first pointer index in the coordinate
+     *      space of the device display.
+     *
+     * @see #getY()
      * @see #AXIS_Y
      */
     public final float getRawY() {
@@ -2709,13 +2731,38 @@
     }
 
     /**
-     * Returns the original raw X coordinate of this event.  For touch
-     * events on the screen, this is the original location of the event
-     * on the screen, before it had been adjusted for the containing window
-     * and views.
+     * Returns the X coordinate of the pointer referenced by
+     * {@code pointerIndex} for this motion event. The coordinate is in the
+     * coordinate space of the device display, irrespective of system
+     * decorations and whether or not the system is in multi-window mode. If the
+     * app spans multiple screens in a multiple-screen environment, the
+     * coordinate space includes all of the spanned screens.
      *
-     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
-     * (the first pointer that is down) to {@link #getPointerCount()}-1.
+     * <p>In multi-window mode, the coordinate space extends beyond the bounds
+     * of the app window to encompass the entire display area. For example, if
+     * the motion event occurs in the right-hand window of split-screen mode in
+     * landscape orientation, the left edge of the screen&mdash;not the left
+     * edge of the window&mdash;is the origin from which the X coordinate is
+     * calculated.
+     *
+     * <p>In multiple-screen scenarios, the coordinate space can span screens.
+     * For example, if the app is spanning both screens of a dual-screen device,
+     * and the motion event occurs on the right-hand screen, the X coordinate is
+     * calculated from the left edge of the left-hand screen to the point of the
+     * motion event on the right-hand screen. When the app is restricted to a
+     * single screen in a multiple-screen environment, the coordinate space
+     * includes only the screen on which the app is running.
+     *
+     * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+     * pointer referenced by {@code pointerIndex}.
+     *
+     * @param pointerIndex Index of the pointer for which the X coordinate is
+     *      returned. May be a value in the range of 0 (the first pointer that
+     *      is down) to {@link #getPointerCount()} - 1.
+     * @return The X coordinate of the pointer referenced by
+     *      {@code pointerIndex} for this motion event. The unit is pixels. The
+     *      value may contain a fractional portion for devices that are subpixel
+     *      precise.
      *
      * @see #getX(int)
      * @see #AXIS_X
@@ -2725,13 +2772,38 @@
     }
 
     /**
-     * Returns the original raw Y coordinate of this event.  For touch
-     * events on the screen, this is the original location of the event
-     * on the screen, before it had been adjusted for the containing window
-     * and views.
+     * Returns the Y coordinate of the pointer referenced by
+     * {@code pointerIndex} for this motion event. The coordinate is in the
+     * coordinate space of the device display, irrespective of system
+     * decorations and whether or not the system is in multi-window mode. If the
+     * app spans multiple screens in a multiple-screen environment, the
+     * coordinate space includes all of the spanned screens.
      *
-     * @param pointerIndex Raw index of pointer to retrieve.  Value may be from 0
-     * (the first pointer that is down) to {@link #getPointerCount()}-1.
+     * <p>In multi-window mode, the coordinate space extends beyond the bounds
+     * of the app window to encompass the entire device screen. For example, if
+     * the motion event occurs in the lower window of split-screen mode in
+     * portrait orientation, the top edge of the screen&mdash;not the top edge
+     * of the window&mdash;is the origin from which the Y coordinate is
+     * determined.
+     *
+     * <p>In multiple-screen scenarios, the coordinate space can span screens.
+     * For example, if the app is spanning both screens of a dual-screen device
+     * that's rotated 90 degrees, and the motion event occurs on the lower
+     * screen, the Y coordinate is calculated from the top edge of the upper
+     * screen to the point of the motion event on the lower screen. When the app
+     * is restricted to a single screen in a multiple-screen environment, the
+     * coordinate space includes only the screen on which the app is running.
+     *
+     * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+     * pointer referenced by {@code pointerIndex}.
+     *
+     * @param pointerIndex Index of the pointer for which the Y coordinate is
+     *      returned. May be a value in the range of 0 (the first pointer that
+     *      is down) to {@link #getPointerCount()} - 1.
+     * @return The Y coordinate of the pointer referenced by
+     *      {@code pointerIndex} for this motion event. The unit is pixels. The
+     *      value may contain a fractional portion for devices that are subpixel
+     *      precise.
      *
      * @see #getY(int)
      * @see #AXIS_Y
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f2ddf52..ffa577a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -28283,7 +28283,7 @@
      *     {@link InputDevice#SOURCE_MOUSE_RELATIVE}, and relative position changes will be
      *     available through {@link MotionEvent#getX} and {@link MotionEvent#getY}.</li>
      *
-     *     <li>Events from a touchpad will be delivered with the source
+     *     <li>Events from a touchpad or trackpad will be delivered with the source
      *     {@link InputDevice#SOURCE_TOUCHPAD}, where the absolute position of each of the pointers
      *     on the touchpad will be available through {@link MotionEvent#getX(int)} and
      *     {@link MotionEvent#getY(int)}, and their relative movements are stored in
@@ -28292,6 +28292,12 @@
      *     <li>Events from other types of devices, such as touchscreens, will not be affected.</li>
      * </ul>
      * <p>
+     * When pointer capture changes, connected mouse and trackpad devices may be reconfigured,
+     * and their properties (such as their sources or motion ranges) may change. Use an
+     * {@link android.hardware.input.InputManager.InputDeviceListener} to be notified when a device
+     * changes (which may happen after enabling or disabling pointer capture), and use
+     * {@link InputDevice#getDevice(int)} to get the updated {@link InputDevice}.
+     * <p>
      * Events captured through pointer capture will be dispatched to
      * {@link OnCapturedPointerListener#onCapturedPointer(View, MotionEvent)} if an
      * {@link OnCapturedPointerListener} is set, and otherwise to
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 7bb1ed8..9699c60 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1176,6 +1176,19 @@
         final Intent resolveIntent = new Intent(originalIntent);
         resolveIntent.setComponent(cn);
         resolveIntent.setAction(Intent.ACTION_EDIT);
+        String originalAction = originalIntent.getAction();
+        if (Intent.ACTION_SEND.equals(originalAction)) {
+            if (resolveIntent.getData() == null) {
+                Uri uri = resolveIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+                if (uri != null) {
+                    String mimeType = getContentResolver().getType(uri);
+                    resolveIntent.setDataAndType(uri, mimeType);
+                }
+            }
+        } else {
+            Log.e(TAG, originalAction + " is not supported.");
+            return null;
+        }
         final ResolveInfo ri = getPackageManager().resolveActivity(
                 resolveIntent, PackageManager.GET_META_DATA);
         if (ri == null || ri.activityInfo == null) {
diff --git a/core/java/com/android/internal/appwidget/OWNERS b/core/java/com/android/internal/appwidget/OWNERS
new file mode 100644
index 0000000..0add4f6
--- /dev/null
+++ b/core/java/com/android/internal/appwidget/OWNERS
@@ -0,0 +1,2 @@
+include /core/java/android/appwidget/OWNERS
+
diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
index 419b1f8..d69a240 100644
--- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
@@ -16,7 +16,7 @@
 package com.android.internal.policy;
 
 interface IKeyguardStateCallback {
-    void onShowingStateChanged(boolean showing);
+    void onShowingStateChanged(boolean showing, int userId);
     void onSimSecureStateChanged(boolean simSecure);
     void onInputRestrictedStateChanged(boolean inputRestricted);
     void onTrustedChanged(boolean trusted);
diff --git a/core/java/com/android/internal/usb/DumpUtils.java b/core/java/com/android/internal/usb/DumpUtils.java
index 3260136..744fe59 100644
--- a/core/java/com/android/internal/usb/DumpUtils.java
+++ b/core/java/com/android/internal/usb/DumpUtils.java
@@ -244,7 +244,8 @@
         writeContaminantPresenceStatus(dump, "contaminant_presence_status",
                 UsbPortStatusProto.CONTAMINANT_PRESENCE_STATUS,
                 status.getContaminantDetectionStatus());
-
+        dump.write("usb_data_enabled", UsbPortStatusProto.USB_DATA_ENABLED,
+                status.getUsbDataStatus());
         dump.end(token);
     }
 }
diff --git a/core/java/com/android/internal/usb/OWNERS b/core/java/com/android/internal/usb/OWNERS
new file mode 100644
index 0000000..f7b2a37
--- /dev/null
+++ b/core/java/com/android/internal/usb/OWNERS
@@ -0,0 +1 @@
+include /services/usb/OWNERS
diff --git a/core/java/com/android/internal/util/VirtualRefBasePtr.java b/core/java/com/android/internal/util/VirtualRefBasePtr.java
index 52306f1..13ddc06 100644
--- a/core/java/com/android/internal/util/VirtualRefBasePtr.java
+++ b/core/java/com/android/internal/util/VirtualRefBasePtr.java
@@ -18,9 +18,12 @@
 
 /**
  * Helper class that contains a strong reference to a VirtualRefBase native
- * object. This will incStrong in the ctor, and decStrong in the finalizer
+ * object. This will incStrong in the ctor, and decStrong in the finalizer.
+ * It currently does no accounting of natively allocated memory, for the
+ * benefit of either GC triggering or heap profiling.
  */
 public final class VirtualRefBasePtr {
+    // TODO(b/231729094): Convert to NativeAllocationRegistry?
     private long mNativePtr;
 
     public VirtualRefBasePtr(long ptr) {
@@ -28,6 +31,14 @@
         nIncStrong(mNativePtr);
     }
 
+    /*
+     * Return the RefBase / VirtualLightRefBase native pointer.  Warning: The
+     * caller must ensure that the VirtualRefBasePtr object remains reachable
+     * while the result is in use. Ideally, the caller should invoke
+     * {@link java.lang.ref.Reference#reachabilityFence}
+     * on the VirtualRefBasePtr object (or on an object that refers to it) as
+     * soon as the result is no longer needed.
+     */
     public long get() {
         return mNativePtr;
     }
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index 8e68be0..d068a3a 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -1,4 +1,4 @@
-per-file PointerLocationView.java = michaelwr@google.com, svv@google.com
+per-file PointerLocationView.java = file:/INPUT_OWNERS
 per-file RecyclerView.java = mount@google.com
 per-file ViewPager.java = mount@google.com
 
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 4072687..361988c 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -66,6 +66,7 @@
 per-file android_graphics_* = file:/graphics/java/android/graphics/OWNERS
 per-file android_hardware_HardwareBuffer.cpp = file:/graphics/java/android/graphics/OWNERS
 per-file android_hardware_SyncFence.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file android_os_GraphicsEnvironment.cpp = file:platform/frameworks/native:/opengl/OWNERS
 
 ### Text ###
 per-file android_text_* = file:/core/java/android/text/OWNERS
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 42cf1f4..9bd0700 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -257,7 +257,7 @@
     err = socket_read_all(env, object, fd, &buf, 1);
 
     if (err < 0) {
-        jniThrowIOException(env, errno);
+        // socket_read_all has already thrown
         return (jint)0;
     }
 
diff --git a/core/jni/android_util_Binder.h b/core/jni/android_util_Binder.h
index 9098d46..d73db62 100644
--- a/core/jni/android_util_Binder.h
+++ b/core/jni/android_util_Binder.h
@@ -24,8 +24,18 @@
 
 namespace android {
 
-// Converstion to/from Java IBinder Object and C++ IBinder instance.
+/**
+ * Conversion to Java IBinder Object from C++ IBinder instance.
+ *
+ * WARNING: this function returns global and local references. This can be
+ * figured out using GetObjectRefType. Though, when this function is called
+ * from within a Java context, the local ref will automatically be cleaned
+ * up. If this is called outside of a Java frame,
+ * PushObjectFrame/PopObjectFrame can simulate this automatic cleanup. The
+ * platform provides ScopedLocalFrame as an RAII object for this.
+ */
 extern jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val);
+/** Conversion from Java IBinder Object to C++ IBinder instance. */
 extern sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj);
 
 extern jobject newParcelFileDescriptor(JNIEnv* env, jobject fileDesc);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5023927..1122c20 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -110,6 +110,8 @@
 
 using android::zygote::ZygoteFailure;
 
+using Action = android_mallopt_gwp_asan_options_t::Action;
+
 // This type is duplicated in fd_utils.h
 typedef const std::function<void(std::string)>& fail_fn_t;
 
@@ -1151,8 +1153,8 @@
   }
 }
 
-// Relabel all directories under a path non-recursively.
-static void relabelAllDirs(const char* path, const char* context, fail_fn_t fail_fn) {
+// Relabel the subdirectories and symlinks in the given directory, non-recursively.
+static void relabelSubdirs(const char* path, const char* context, fail_fn_t fail_fn) {
   DIR* dir = opendir(path);
   if (dir == nullptr) {
     fail_fn(CREATE_ERROR("Failed to opendir %s", path));
@@ -1175,38 +1177,40 @@
 }
 
 /**
- * Make other apps data directory not visible in CE, DE storage.
+ * Hide the CE and DE data directories of non-related apps.
  *
- * Apps without app data isolation can detect if another app is installed on system,
- * by "touching" other apps data directory like /data/data/com.whatsapp, if it returns
- * "Permission denied" it means apps installed, otherwise it returns "File not found".
- * Traditional file permissions or SELinux can only block accessing those directories but
- * can't fix fingerprinting like this.
- * We fix it by "overlaying" data directory, and only relevant app data packages exists
- * in data directories.
+ * Without this, apps can detect if any app is installed by trying to "touch" the app's CE
+ * or DE data directory, e.g. /data/data/com.whatsapp.  This fails with EACCES if the app
+ * is installed, or ENOENT if it's not.  Traditional file permissions or SELinux can only
+ * block accessing those directories but can't fix fingerprinting like this.
+ *
+ * Instead, we hide non-related apps' data directories from the filesystem entirely by
+ * mounting tmpfs instances over their parent directories and bind-mounting in just the
+ * needed app data directories.  This is done in a private mount namespace.
  *
  * Steps:
- * 1). Collect a list of all related apps (apps with same uid and allowlisted apps) data info
- * (package name, data stored volume uuid, and inode number of its CE data directory)
- * 2). Mount tmpfs on /data/data, /data/user(_de) and /mnt/expand, so apps no longer
- * able to access apps data directly.
- * 3). For each related app, create its app data directory and bind mount the actual content
- * from apps data mirror directory. This works on both CE and DE storage, as DE storage
- * is always available even storage is FBE locked, while we use inode number to find
- * the encrypted DE directory in mirror so we can still bind mount it successfully.
+ * (1) Collect a list of all related apps (apps with same uid and allowlisted apps) data info
+ *     (package name, data stored volume uuid, and inode number of its CE data directory)
+ * (2) Mount tmpfs on /data/data and /data/user{,_de}, and on /mnt/expand/$volume/user{,_de}
+ *     for all adoptable storage volumes.  This hides all app data directories.
+ * (3) For each related app, create stubs for its data directories in the relevant tmpfs
+ *     instances, then bind mount in the actual directories from /data_mirror.  This works
+ *     for both the CE and DE directories.  DE storage is always unlocked, whereas the
+ *     app's CE directory can be found via inode number if CE storage is locked.
  *
- * Example:
- * 0). Assuming com.android.foo CE data is stored in /data/data and no shared uid
- * 1). Mount a tmpfs on /data/data, /data/user, /data/user_de, /mnt/expand
- * List = ["com.android.foo", "null" (volume uuid "null"=default),
- * 123456 (inode number)]
- * 2). On DE storage, we create a directory /data/user_de/0/com.com.android.foo, and bind
- * mount (in the app's mount namespace) it from /data_mirror/data_de/0/com.android.foo.
- * 3). We do similar for CE storage. But in direct boot mode, as /data_mirror/data_ce/0/ is
- * encrypted, we can't find a directory with name com.android.foo on it, so we will
- * use the inode number to find the right directory instead, which that directory content will
- * be decrypted after storage is decrypted.
- *
+ * Example assuming user 0, app "com.android.foo", no shared uid, and no adoptable storage:
+ * (1) Info = ["com.android.foo", "null" (volume uuid "null"=default), "123456" (inode number)]
+ * (2) Mount tmpfs on /data/data, /data/user, and /data/user_de.
+ * (3) For DE storage, create a directory /data/user_de/0/com.android.foo and bind mount
+ *     /data_mirror/data_de/0/com.android.foo onto it.
+ * (4) Do similar for CE storage.  But if the device is in direct boot mode, then CE
+ *     storage will be locked, so the app's CE data directory won't exist at the usual
+ *     path /data_mirror/data_ce/0/com.android.foo.  It will still exist in
+ *     /data_mirror/data_ce/0, but its filename will be an unpredictable no-key name.  In
+ *     this case, we use the inode number to find the right directory instead.  Note that
+ *     the bind-mounted app CE data directory will remain locked.  It will be unlocked
+ *     automatically if/when the user's CE storage is unlocked, since adding an encryption
+ *     key takes effect on a whole filesystem instance including all its mounts.
  */
 static void isolateAppData(JNIEnv* env, const std::vector<std::string>& merged_data_info_list,
     uid_t uid, const char* process_name,
@@ -1227,11 +1231,19 @@
   snprintf(internalDePath, PATH_MAX, "/data/user_de");
   snprintf(externalPrivateMountPath, PATH_MAX, "/mnt/expand");
 
-  char* dataDataContext = nullptr;
-  if (getfilecon(internalDePath, &dataDataContext) < 0) {
-    fail_fn(CREATE_ERROR("Unable to getfilecon on %s %s", internalDePath,
+  // Get the "u:object_r:system_userdir_file:s0" security context.  This can be
+  // gotten from several different places; we use /data/user.
+  char* dataUserdirContext = nullptr;
+  if (getfilecon(internalCePath, &dataUserdirContext) < 0) {
+    fail_fn(CREATE_ERROR("Unable to getfilecon on %s %s", internalCePath,
         strerror(errno)));
   }
+  // Get the "u:object_r:system_data_file:s0" security context.  This can be
+  // gotten from several different places; we use /data/misc.
+  char* dataFileContext = nullptr;
+  if (getfilecon("/data/misc", &dataFileContext) < 0) {
+    fail_fn(CREATE_ERROR("Unable to getfilecon on /data/misc %s", strerror(errno)));
+  }
 
   MountAppDataTmpFs(internalLegacyCePath, fail_fn);
   MountAppDataTmpFs(internalCePath, fail_fn);
@@ -1326,19 +1338,19 @@
   // the file operations on tmpfs. If we set the label when we mount
   // tmpfs, SELinux will not happy as we are changing system_data_files.
   // Relabel dir under /data/user, including /data/user/0
-  relabelAllDirs(internalCePath, dataDataContext, fail_fn);
+  relabelSubdirs(internalCePath, dataFileContext, fail_fn);
 
   // Relabel /data/user
-  relabelDir(internalCePath, dataDataContext, fail_fn);
+  relabelDir(internalCePath, dataUserdirContext, fail_fn);
 
   // Relabel /data/data
-  relabelDir(internalLegacyCePath, dataDataContext, fail_fn);
+  relabelDir(internalLegacyCePath, dataFileContext, fail_fn);
 
-  // Relabel dir under /data/user_de
-  relabelAllDirs(internalDePath, dataDataContext, fail_fn);
+  // Relabel subdirectories of /data/user_de
+  relabelSubdirs(internalDePath, dataFileContext, fail_fn);
 
   // Relabel /data/user_de
-  relabelDir(internalDePath, dataDataContext, fail_fn);
+  relabelDir(internalDePath, dataUserdirContext, fail_fn);
 
   // Relabel CE and DE dirs under /mnt/expand
   dir = opendir(externalPrivateMountPath);
@@ -1351,14 +1363,15 @@
     auto cePath = StringPrintf("%s/user", volPath.c_str());
     auto dePath = StringPrintf("%s/user_de", volPath.c_str());
 
-    relabelAllDirs(cePath.c_str(), dataDataContext, fail_fn);
-    relabelDir(cePath.c_str(), dataDataContext, fail_fn);
-    relabelAllDirs(dePath.c_str(), dataDataContext, fail_fn);
-    relabelDir(dePath.c_str(), dataDataContext, fail_fn);
+    relabelSubdirs(cePath.c_str(), dataFileContext, fail_fn);
+    relabelDir(cePath.c_str(), dataUserdirContext, fail_fn);
+    relabelSubdirs(dePath.c_str(), dataFileContext, fail_fn);
+    relabelDir(dePath.c_str(), dataUserdirContext, fail_fn);
   }
   closedir(dir);
 
-  freecon(dataDataContext);
+  freecon(dataUserdirContext);
+  freecon(dataFileContext);
 }
 
 static void insertPackagesToMergedList(JNIEnv* env,
@@ -1597,10 +1610,11 @@
     // since the directory is owned by root.
     if (!is_system_server && getuid() == 0) {
         const int rc = createProcessGroup(uid, getpid());
-        if (rc == -EROFS) {
-            ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
-        } else if (rc != 0) {
-            ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
+        if (rc != 0) {
+            fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
+                                                "CONFIG_CGROUP_CPUACCT?")
+                                 : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
+                                                /* pid= */ 0, strerror(-rc)));
         }
     }
 
@@ -1717,16 +1731,24 @@
     // runtime.
     runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT;
 
-    bool forceEnableGwpAsan = false;
+    const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
+    android_mallopt_gwp_asan_options_t gwp_asan_options;
+    // The system server doesn't have its nice name set by the time SpecializeCommon is called.
+    gwp_asan_options.program_name = nice_name_ptr ?: process_name;
     switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
         default:
         case RuntimeFlags::GWP_ASAN_LEVEL_NEVER:
+            gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
             break;
         case RuntimeFlags::GWP_ASAN_LEVEL_ALWAYS:
-            forceEnableGwpAsan = true;
-            [[fallthrough]];
+            gwp_asan_options.desire = Action::TURN_ON_FOR_APP;
+            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
+            break;
         case RuntimeFlags::GWP_ASAN_LEVEL_LOTTERY:
-            android_mallopt(M_INITIALIZE_GWP_ASAN, &forceEnableGwpAsan, sizeof(forceEnableGwpAsan));
+            gwp_asan_options.desire = Action::TURN_ON_WITH_SAMPLING;
+            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
+            break;
     }
     // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART
     // runtime.
@@ -1739,7 +1761,6 @@
     AStatsSocket_close();
 
     const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
-    const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
 
     if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
         fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index 7e26952..4f3eeb0 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -434,8 +434,9 @@
             optional string vibrator = 37;
             optional string virtual_device = 38;
             optional string vulkan = 39;
+            optional string egl_legacy = 40;
 
-            // Next Tag: 40
+            // Next Tag: 41
         }
         optional Hardware hardware = 27;
 
@@ -555,4 +556,3 @@
 
     // Next Tag: 32
 }
-
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index 45f8c132..cd002da 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -195,9 +195,19 @@
 message UsbPortManagerProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
 
+    enum HalVersion {
+        V_UNKNOWN = 0;
+        V1_0 = 10;
+        V1_1 = 11;
+        V1_2 = 12;
+        V1_3 = 13;
+        V2 = 20;
+    }
+
     optional bool is_simulation_active = 1;
     repeated UsbPortInfoProto usb_ports = 2;
     optional bool enable_usb_data_signaling = 3;
+    optional HalVersion hal_version = 4;
 }
 
 message UsbPortInfoProto {
@@ -253,6 +263,7 @@
     optional DataRole data_role = 4;
     repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
     optional android.service.ContaminantPresenceStatus contaminant_presence_status = 6;
+    optional bool usb_data_enabled = 7;
 }
 
 message UsbPortStatusRoleCombinationProto {
diff --git a/core/res/OWNERS b/core/res/OWNERS
index a20b895..c66e64e 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -34,4 +34,8 @@
 per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
 
 # Car
-per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
\ No newline at end of file
+per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
+
+# Telephony
+per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS
+per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c5d50fb..a8ab1a8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2572,36 +2572,10 @@
     <string-array name="config_mobile_tcp_buffers">
     </string-array>
 
-    <!-- Configure tcp buffer sizes per network type in the form:
-         network-type:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
-
-         The network-type must be a valid DataConfigNetworkType value. If no value is found for the
-         network-type in use, config_tcp_buffers will be used instead.
-    -->
-    <string-array name="config_network_type_tcp_buffers">
-    </string-array>
-
-    <!-- Configure tcp buffer sizes in the form:
-         rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
-         If this is configured as an empty string, the system default will be applied.
-
-         For now this config is used by mobile data only. In the future it should be
-         used by Wi-Fi as well.
-    -->
-    <string name="config_tcp_buffers" translatable="false"></string>
-
     <!-- Configure ethernet tcp buffersizes in the form:
          rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
     <string name="config_ethernet_tcp_buffers" translatable="false">524288,1048576,3145728,524288,1048576,2097152</string>
 
-    <!-- What source to use to estimate link upstream and downstream bandwidth capacities.
-         Default is bandwidth_estimator.
-         Values are bandwidth_estimator, carrier_config and modem. -->
-    <string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
-
-    <!-- Whether force to enable telephony new data stack or not -->
-    <bool name="config_force_enable_telephony_new_data_stack">false</bool>
-
     <!-- Whether WiFi display is supported by this device.
          There are many prerequisites for this feature to work correctly.
          Here are a few of them:
@@ -3148,27 +3122,6 @@
     <!-- String array containing numbers that shouldn't be logged. Country-specific. -->
     <string-array name="unloggable_phone_numbers" />
 
-    <!-- Cellular data service package name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wwan_data_service_package" translatable="false">com.android.phone</string>
-
-    <!-- IWLAN data service package name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wlan_data_service_package" translatable="false"></string>
-
-    <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
-         tunnels across service restart. If iwlan tunnels are not persisted across restart,
-         Framework will clean up dangling data connections when service restarts -->
-    <bool name="config_wlan_data_service_conn_persistence_on_restart">true</bool>
-
-    <!-- Cellular data service class name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wwan_data_service_class" translatable="false"></string>
-
-    <!-- IWLAN data service class name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wlan_data_service_class" translatable="false"></string>
-
     <bool name="config_networkSamplingWakesDevice">true</bool>
 
     <!--From SmsMessage-->
@@ -3254,11 +3207,6 @@
          and one pSIM) -->
     <integer name="config_num_physical_slots">1</integer>
 
-    <!-- When a radio power off request is received, we will delay completing the request until
-         either IMS moves to the deregistered state or the timeout defined by this configuration
-         elapses. If 0, this feature is disabled and we do not delay radio power off requests.-->
-    <integer name="config_delay_for_ims_dereg_millis">0</integer>
-
     <!--Thresholds for LTE dbm in status bar-->
     <integer-array translatable="false" name="config_lteDbmThresholds">
         <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
@@ -4194,24 +4142,6 @@
 
     <bool name="config_keepRestrictedProfilesInBackground">true</bool>
 
-    <!-- Cellular network service package name to bind to by default. -->
-    <string name="config_wwan_network_service_package" translatable="false">com.android.phone</string>
-
-    <!-- Cellular network service class name to bind to by default.-->
-    <string name="config_wwan_network_service_class" translatable="false"></string>
-
-    <!-- IWLAN network service package name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wlan_network_service_package" translatable="false"></string>
-
-    <!-- IWLAN network service class name to bind to by default. If none is specified in an overlay, an
-         empty string is passed in -->
-    <string name="config_wlan_network_service_class" translatable="false"></string>
-    <!-- Telephony qualified networks service package name to bind to by default. -->
-    <string name="config_qualified_networks_service_package" translatable="false"></string>
-
-    <!-- Telephony qualified networks service class name to bind to by default. -->
-    <string name="config_qualified_networks_service_class" translatable="false"></string>
     <!-- Wear devices: Controls the radios affected by Activity Mode. -->
     <string-array name="config_wearActivityModeRadios">
         <item>"wifi"</item>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
new file mode 100644
index 0000000..682ce46
--- /dev/null
+++ b/core/res/res/values/config_telephony.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <!-- This file defines Android telephony related resources -->
+
+    <!-- Whether force disabling telephony new data stack or not -->
+    <bool name="config_force_disable_telephony_new_data_stack">false</bool>
+    <java-symbol type="bool" name="config_force_disable_telephony_new_data_stack" />
+
+    <!-- Configure tcp buffer sizes per network type in the form:
+         network-type:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
+
+         The network-type must be a valid DataConfigNetworkType value. If no value is found for the
+         network-type in use, config_tcp_buffers will be used instead.
+    -->
+    <string-array name="config_network_type_tcp_buffers">
+    </string-array>
+    <java-symbol type="array" name="config_network_type_tcp_buffers" />
+
+    <!-- Configure tcp buffer sizes in the form:
+         rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
+         If this is configured as an empty string, the system default will be applied.
+    -->
+    <string name="config_tcp_buffers" translatable="false">2097152,6291456,16777216,512000,2097152,8388608</string>
+    <java-symbol type="string"  name="config_tcp_buffers" />
+
+    <!-- What source to use to estimate link upstream and downstream bandwidth capacities.
+         Default is bandwidth_estimator.
+         Values are bandwidth_estimator, carrier_config and modem. -->
+    <string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
+    <java-symbol type="string" name="config_bandwidthEstimateSource" />
+
+    <!-- Whether to adopt the predefined handover policies for IWLAN.
+         {@see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY}
+    -->
+    <bool name="config_enable_iwlan_handover_policy">true</bool>
+    <java-symbol type="bool" name="config_enable_iwlan_handover_policy" />
+
+    <!-- When a radio power off request is received, we will delay completing the request until
+         either IMS moves to the deregistered state or the timeout defined by this configuration
+         elapses. If 0, this feature is disabled and we do not delay radio power off requests.-->
+    <integer name="config_delay_for_ims_dereg_millis">0</integer>
+    <java-symbol type="integer" name="config_delay_for_ims_dereg_millis" />
+
+    <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
+         tunnels across service restart. If iwlan tunnels are not persisted across restart,
+         Framework will clean up dangling data connections when service restarts -->
+    <bool name="config_wlan_data_service_conn_persistence_on_restart">true</bool>
+    <java-symbol type="bool" name="config_wlan_data_service_conn_persistence_on_restart" />
+
+    <!-- Cellular data service package name to bind to by default. If none is specified in an
+         overlay, an empty string is passed in -->
+    <string name="config_wwan_data_service_package" translatable="false">com.android.phone</string>
+    <java-symbol type="string" name="config_wwan_data_service_package" />
+
+    <!-- IWLAN data service package name to bind to by default. If none is specified in an overlay,
+         an empty string is passed in -->
+    <string name="config_wlan_data_service_package" translatable="false"></string>
+    <java-symbol type="string" name="config_wlan_data_service_package" />
+
+    <!-- Cellular data service class name to bind to by default. If none is specified in an overlay,
+         an empty string is passed in -->
+    <string name="config_wwan_data_service_class" translatable="false"></string>
+    <java-symbol type="string" name="config_wwan_data_service_class" />
+
+    <!-- IWLAN data service class name to bind to by default. If none is specified in an overlay, an
+         empty string is passed in -->
+    <string name="config_wlan_data_service_class" translatable="false"></string>
+    <java-symbol type="string" name="config_wlan_data_service_class" />
+
+    <!-- Cellular network service package name to bind to by default. -->
+    <string name="config_wwan_network_service_package" translatable="false">
+        com.android.phone
+    </string>
+    <java-symbol type="string" name="config_wwan_network_service_package" />
+
+    <!-- Cellular network service class name to bind to by default.-->
+    <string name="config_wwan_network_service_class" translatable="false"></string>
+    <java-symbol type="string" name="config_wwan_network_service_class" />
+
+    <!-- IWLAN network service package name to bind to by default. If none is specified in an
+         overlay, an empty string is passed in -->
+    <string name="config_wlan_network_service_package" translatable="false"></string>
+    <java-symbol type="string" name="config_wlan_network_service_package" />
+
+    <!-- IWLAN network service class name to bind to by default. If none is specified in an overlay,
+         an empty string is passed in -->
+    <string name="config_wlan_network_service_class" translatable="false"></string>
+    <java-symbol type="string" name="config_wlan_network_service_class" />
+
+    <!-- Telephony qualified networks service package name to bind to by default. -->
+    <string name="config_qualified_networks_service_package" translatable="false"></string>
+    <java-symbol type="string" name="config_qualified_networks_service_package" />
+
+    <!-- Telephony qualified networks service class name to bind to by default. -->
+    <string name="config_qualified_networks_service_class" translatable="false"></string>
+    <java-symbol type="string" name="config_qualified_networks_service_class" />
+
+    <!-- Whether enhanced IWLAN handover check is enabled. If enabled, telephony frameworks
+         will not perform handover if the target transport is out of service, or VoPS not
+         supported. The network will be torn down on the source transport, and will be
+         re-established on the target transport when condition is allowed for bringing up a
+         new network. -->
+    <bool name="config_enhanced_iwlan_handover_check">true</bool>
+    <java-symbol type="bool" name="config_enhanced_iwlan_handover_check" />
+</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6e0fd91..4ad95b6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -294,17 +294,6 @@
   <java-symbol type="bool" name="config_enableBurnInProtection" />
   <java-symbol type="bool" name="config_hotswapCapable" />
   <java-symbol type="bool" name="config_mms_content_disposition_support" />
-  <java-symbol type="string" name="config_wwan_network_service_package" />
-  <java-symbol type="string" name="config_wlan_network_service_package" />
-  <java-symbol type="string" name="config_wwan_network_service_class" />
-  <java-symbol type="string" name="config_wlan_network_service_class" />
-  <java-symbol type="bool" name="config_wlan_data_service_conn_persistence_on_restart" />
-  <java-symbol type="string" name="config_wwan_data_service_package" />
-  <java-symbol type="string" name="config_wlan_data_service_package" />
-  <java-symbol type="string" name="config_wwan_data_service_class" />
-  <java-symbol type="string" name="config_wlan_data_service_class" />
-  <java-symbol type="string" name="config_qualified_networks_service_package" />
-  <java-symbol type="string" name="config_qualified_networks_service_class" />
   <java-symbol type="bool" name="config_networkSamplingWakesDevice" />
   <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
   <java-symbol type="bool" name="config_sip_wifi_only" />
@@ -466,9 +455,6 @@
   <java-symbol type="integer" name="config_safe_media_volume_usb_mB" />
   <java-symbol type="integer" name="config_mobile_mtu" />
   <java-symbol type="array"   name="config_mobile_tcp_buffers" />
-  <java-symbol type="array"   name="config_network_type_tcp_buffers" />
-  <java-symbol type="string"  name="config_tcp_buffers" />
-  <java-symbol type="bool" name="config_force_enable_telephony_new_data_stack" />
   <java-symbol type="integer" name="config_volte_replacement_rat"/>
   <java-symbol type="integer" name="config_valid_wappush_index" />
   <java-symbol type="integer" name="config_overrideHasPermanentMenuKey" />
@@ -480,10 +466,8 @@
   <java-symbol type="string" name="config_deviceSpecificDevicePolicyManagerService" />
   <java-symbol type="string" name="config_deviceSpecificAudioService" />
   <java-symbol type="integer" name="config_num_physical_slots" />
-  <java-symbol type="integer" name="config_delay_for_ims_dereg_millis" />
   <java-symbol type="array" name="config_integrityRuleProviderPackages" />
   <java-symbol type="bool" name="config_useAssistantVolume" />
-  <java-symbol type="string" name="config_bandwidthEstimateSource" />
   <java-symbol type="integer" name="config_smartSelectionInitializedTimeoutMillis" />
   <java-symbol type="integer" name="config_smartSelectionInitializingTimeoutMillis" />
   <java-symbol type="bool" name="config_hibernationDeletesOatArtifactsEnabled"/>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index d1d86a7..dab4f1b 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -156,7 +156,7 @@
 
     <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU:
          https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
-    <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" />
+    <shortcode country="it" pattern="\\d{5}" premium="44[0-4]\\d{2}|47[0-4]\\d{2}|48[0-4]\\d{2}|44[5-9]\\d{4}|47[5-9]\\d{4}|48[5-9]\\d{4}|455\\d{2}|499\\d{2}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" />
 
     <!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
     <shortcode country="jp" pattern="\\d{1,5}" free="8083" />
diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp
index c112cbb..6f2366e 100644
--- a/core/tests/PackageInstallerSessions/Android.bp
+++ b/core/tests/PackageInstallerSessions/Android.bp
@@ -50,7 +50,6 @@
         ":PackageManagerTestAppVersion1",
     ],
 
-    platform_apis: true,
     sdk_version: "core_platform",
     test_suites: ["device-tests"],
 }
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index f87797a..2b34ee2 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -36,7 +36,6 @@
     ],
     test_suites: ["general-tests"],
     sdk_version: "test_current",
-    platform_apis: true,
 }
 
 filegroup {
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 05ec00f..f971af1 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -72,7 +72,6 @@
         "libpowermanagertest_jni",
     ],
 
-    platform_apis: true,
     sdk_version: "core_platform",
     test_suites: ["device-tests"],
 
diff --git a/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java b/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java
new file mode 100644
index 0000000..90b3305
--- /dev/null
+++ b/core/tests/coretests/src/android/app/time/ExternalTimeSuggestionTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.time;
+
+import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.ShellCommand;
+
+import org.junit.Test;
+
+/**
+ * Tests for non-SDK methods on {@link ExternalTimeSuggestion}.
+ * Also see {@link android.app.time.cts.ExternalTimeSuggestionTest}
+ */
+public class ExternalTimeSuggestionTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noReferenceTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--unix_epoch_time 12345");
+        ExternalTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUnixEpochTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321");
+        ExternalTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_validSuggestion() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
+        ExternalTimeSuggestion expectedSuggestion = new ExternalTimeSuggestion(54321L, 12345L);
+        ExternalTimeSuggestion actualSuggestion =
+                ExternalTimeSuggestion.parseCommandLineArg(testShellCommand);
+        assertEquals(expectedSuggestion, actualSuggestion);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345 --bad_arg 0");
+        ExternalTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+}
diff --git a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
index e248010..af403a2 100644
--- a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
@@ -18,10 +18,12 @@
 
 import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
 import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
 import org.junit.Test;
@@ -63,4 +65,36 @@
         GnssTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
         assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noReferenceTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--unix_epoch_time 12345");
+        GnssTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUnixEpochTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321");
+        GnssTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_validSuggestion() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(54321L, 12345L);
+        GnssTimeSuggestion expectedSuggestion = new GnssTimeSuggestion(timeSignal);
+        GnssTimeSuggestion actualSuggestion =
+                GnssTimeSuggestion.parseCommandLineArg(testShellCommand);
+        assertEquals(expectedSuggestion, actualSuggestion);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345 --bad_arg 0");
+        GnssTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java
index 750ffa1..94218cd 100644
--- a/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/ManualTimeSuggestionTest.java
@@ -18,10 +18,12 @@
 
 import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
 import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
 import org.junit.Test;
@@ -63,4 +65,36 @@
         ManualTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
         assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noReferenceTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--unix_epoch_time 12345");
+        ManualTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUnixEpochTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321");
+        ManualTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_validSuggestion() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(54321L, 12345L);
+        ManualTimeSuggestion expectedSuggestion = new ManualTimeSuggestion(timeSignal);
+        ManualTimeSuggestion actualSuggestion =
+                ManualTimeSuggestion.parseCommandLineArg(testShellCommand);
+        assertEquals(expectedSuggestion, actualSuggestion);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345 --bad_arg 0");
+        ManualTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
index b88c36f..0e09dd3 100644
--- a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
@@ -18,10 +18,12 @@
 
 import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
 import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
 import org.junit.Test;
@@ -63,4 +65,36 @@
         NetworkTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
         assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noReferenceTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--unix_epoch_time 12345");
+        NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUnixEpochTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321");
+        NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_validSuggestion() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(54321L, 12345L);
+        NetworkTimeSuggestion expectedSuggestion = new NetworkTimeSuggestion(timeSignal);
+        NetworkTimeSuggestion actualSuggestion =
+                NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+        assertEquals(expectedSuggestion, actualSuggestion);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345 --bad_arg 0");
+        NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
index cc75579..bb995a8 100644
--- a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
@@ -18,10 +18,12 @@
 
 import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
 import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.os.ShellCommand;
 import android.os.TimestampedValue;
 
 import org.junit.Test;
@@ -95,4 +97,45 @@
             assertEquals(suggestion1.getDebugInfo(), rtSuggestion1.getDebugInfo());
         }
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noSlotIndex() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--reference_time 54321 --unix_epoch_time 12345");
+        TelephonyTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noReferenceTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--slot_index 0 --unix_epoch_time 12345");
+        TelephonyTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_noUnixEpochTime() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--slot_index 0 --reference_time 54321");
+        TelephonyTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
+
+    @Test
+    public void testParseCommandLineArg_validSuggestion() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--slot_index 0 --reference_time 54321 --unix_epoch_time 12345");
+        TelephonyTimeSuggestion expectedSuggestion =
+                new TelephonyTimeSuggestion.Builder(0)
+                        .setUnixEpochTime(new TimestampedValue<>(54321L, 12345L))
+                        .build();
+        TelephonyTimeSuggestion actualSuggestion =
+                TelephonyTimeSuggestion.parseCommandLineArg(testShellCommand);
+        assertEquals(expectedSuggestion, actualSuggestion);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseCommandLineArg_unknownArgument() {
+        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+                "--slot_index 0 --reference_time 54321 --unix_epoch_time 12345 --bad_arg 0");
+        TelephonyTimeSuggestion.parseCommandLineArg(testShellCommand);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java b/core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java
index 8d8290c..4efaed1 100644
--- a/core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java
+++ b/core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java
@@ -26,14 +26,14 @@
 import java.util.List;
 
 /** Utility methods related to {@link ShellCommand} objects used in several tests. */
-final class ShellCommandTestSupport {
+public final class ShellCommandTestSupport {
     private ShellCommandTestSupport() {}
 
-    static ShellCommand createShellCommandWithArgsAndOptions(String argsWithSpaces) {
+    public static ShellCommand createShellCommandWithArgsAndOptions(String argsWithSpaces) {
         return createShellCommandWithArgsAndOptions(Arrays.asList(argsWithSpaces.split(" ")));
     }
 
-    static ShellCommand createShellCommandWithArgsAndOptions(List<String> args) {
+    public static ShellCommand createShellCommandWithArgsAndOptions(List<String> args) {
         ShellCommand command = mock(ShellCommand.class);
         class ArgProvider {
             private int mCount;
diff --git a/graphics/TEST_MAPPING b/graphics/TEST_MAPPING
index 10bd0ee..abeaf19 100644
--- a/graphics/TEST_MAPPING
+++ b/graphics/TEST_MAPPING
@@ -1,7 +1,12 @@
 {
   "presubmit": [
     {
-      "name": "CtsGraphicsTestCases"
+      "name": "CtsGraphicsTestCases",
+      "options": [
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
     }
   ]
 }
diff --git a/keystore/java/android/security/GenerateRkpKey.java b/keystore/java/android/security/GenerateRkpKey.java
index 2e54e63..6981332 100644
--- a/keystore/java/android/security/GenerateRkpKey.java
+++ b/keystore/java/android/security/GenerateRkpKey.java
@@ -16,6 +16,8 @@
 
 package android.security;
 
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,6 +26,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -57,6 +61,21 @@
     private Context mContext;
     private CountDownLatch mCountDownLatch;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, value = {
+            IGenerateRkpKeyService.Status.OK,
+            IGenerateRkpKeyService.Status.NO_NETWORK_CONNECTIVITY,
+            IGenerateRkpKeyService.Status.NETWORK_COMMUNICATION_ERROR,
+            IGenerateRkpKeyService.Status.DEVICE_NOT_REGISTERED,
+            IGenerateRkpKeyService.Status.HTTP_CLIENT_ERROR,
+            IGenerateRkpKeyService.Status.HTTP_SERVER_ERROR,
+            IGenerateRkpKeyService.Status.HTTP_UNKNOWN_ERROR,
+            IGenerateRkpKeyService.Status.INTERNAL_ERROR,
+    })
+    public @interface Status {
+    }
+
     private ServiceConnection mConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName className, IBinder service) {
@@ -81,12 +100,14 @@
         mContext = context;
     }
 
-    private void bindAndSendCommand(int command, int securityLevel) throws RemoteException {
+    @Status
+    private int bindAndSendCommand(int command, int securityLevel) throws RemoteException {
         Intent intent = new Intent(IGenerateRkpKeyService.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        int returnCode = IGenerateRkpKeyService.Status.OK;
         if (comp == null) {
             // On a system that does not use RKP, the RemoteProvisioner app won't be installed.
-            return;
+            return returnCode;
         }
         intent.setComponent(comp);
         mCountDownLatch = new CountDownLatch(1);
@@ -102,7 +123,7 @@
         if (mBinder != null) {
             switch (command) {
                 case NOTIFY_EMPTY:
-                    mBinder.generateKey(securityLevel);
+                    returnCode = mBinder.generateKey(securityLevel);
                     break;
                 case NOTIFY_KEY_GENERATED:
                     mBinder.notifyKeyGenerated(securityLevel);
@@ -112,16 +133,21 @@
             }
         } else {
             Log.e(TAG, "Binder object is null; failed to bind to GenerateRkpKeyService.");
+            returnCode = IGenerateRkpKeyService.Status.INTERNAL_ERROR;
         }
         mContext.unbindService(mConnection);
+        return returnCode;
     }
 
     /**
      * Fulfills the use case of (2) described in the class documentation. Blocks until the
      * RemoteProvisioner application can get new attestation keys signed by the server.
+     * @return the status of the key generation
      */
-    public void notifyEmpty(int securityLevel) throws RemoteException {
-        bindAndSendCommand(NOTIFY_EMPTY, securityLevel);
+    @CheckResult
+    @Status
+    public int notifyEmpty(int securityLevel) throws RemoteException {
+        return bindAndSendCommand(NOTIFY_EMPTY, securityLevel);
     }
 
     /**
diff --git a/keystore/java/android/security/IGenerateRkpKeyService.aidl b/keystore/java/android/security/IGenerateRkpKeyService.aidl
index 5f1d669..eeaeb27 100644
--- a/keystore/java/android/security/IGenerateRkpKeyService.aidl
+++ b/keystore/java/android/security/IGenerateRkpKeyService.aidl
@@ -26,11 +26,35 @@
  * @hide
  */
 interface IGenerateRkpKeyService {
+    @JavaDerive(toString=true)
+    @Backing(type="int")
+    enum Status {
+        /** No error(s) occurred */
+        OK = 0,
+        /** Unable to provision keys due to a lack of internet connectivity. */
+        NO_NETWORK_CONNECTIVITY = 1,
+        /** An error occurred while communicating with the RKP server. */
+        NETWORK_COMMUNICATION_ERROR = 2,
+        /** The given device was not registered with the RKP backend. */
+        DEVICE_NOT_REGISTERED = 4,
+        /** The RKP server returned an HTTP client error, indicating a misbehaving client. */
+        HTTP_CLIENT_ERROR = 5,
+        /** The RKP server returned an HTTP server error, indicating something went wrong on the server. */
+        HTTP_SERVER_ERROR = 6,
+        /** The RKP server returned an HTTP status that is unknown. This should never happen. */
+        HTTP_UNKNOWN_ERROR = 7,
+        /** An unexpected internal error occurred. This should never happen. */
+        INTERNAL_ERROR = 8,
+    }
+
     /**
      * Ping the provisioner service to let it know an app generated a key. This may or may not have
      * consumed a remotely provisioned attestation key, so the RemoteProvisioner app should check.
      */
     oneway void notifyKeyGenerated(in int securityLevel);
-    /** Ping the provisioner service to indicate there are no remaining attestation keys left. */
-    void generateKey(in int securityLevel);
+
+    /**
+     * Ping the provisioner service to indicate there are no remaining attestation keys left.
+     */
+    Status generateKey(in int securityLevel);
 }
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index 3d53cfb..c2cd6ff 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -345,6 +345,12 @@
                 case ResponseCode.KEY_PERMANENTLY_INVALIDATED:
                     return new KeyStoreException(errorCode, "Key permanently invalidated",
                             serviceErrorMessage);
+                case ResponseCode.OUT_OF_KEYS:
+                    // Getting a more specific RKP status requires the security level, which we
+                    // don't have here. Higher layers of the stack can interpret this exception
+                    // and add more flavor.
+                    return new KeyStoreException(errorCode, serviceErrorMessage,
+                            KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE);
                 default:
                     return new KeyStoreException(errorCode, String.valueOf(errorCode),
                             serviceErrorMessage);
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java
index 9ad6f3a..6fff52a 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java
@@ -206,6 +206,8 @@
 
         putSignatureImpl("NONEwithECDSA",
                 PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$NONE");
+        putSignatureImpl("Ed25519",
+                PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$Ed25519");
 
         putSignatureImpl("SHA1withECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA1");
         put("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
index 8289671..5216a90 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
@@ -29,7 +29,10 @@
 import java.io.ByteArrayOutputStream;
 import java.security.InvalidKeyException;
 import java.security.SignatureSpi;
+import java.security.spec.NamedParameterSpec;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Base class for {@link SignatureSpi} providing Android KeyStore backed ECDSA signatures.
@@ -37,6 +40,10 @@
  * @hide
  */
 abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignatureSpiBase {
+    private static final Set<String> ACCEPTED_SIGNING_SCHEMES = Set.of(
+            KeyProperties.KEY_ALGORITHM_EC.toLowerCase(),
+            NamedParameterSpec.ED25519.getName().toLowerCase(),
+            "eddsa");
 
     public final static class NONE extends AndroidKeyStoreECDSASignatureSpi {
         public NONE() {
@@ -114,6 +121,18 @@
         }
     }
 
+    public static final class Ed25519 extends AndroidKeyStoreECDSASignatureSpi {
+        public Ed25519() {
+            // Ed25519 uses an internal digest system.
+            super(KeymasterDefs.KM_DIGEST_NONE);
+        }
+
+        @Override
+        protected String getAlgorithm() {
+            return NamedParameterSpec.ED25519.getName();
+        }
+    }
+
     public final static class SHA1 extends AndroidKeyStoreECDSASignatureSpi {
         public SHA1() {
             super(KeymasterDefs.KM_DIGEST_SHA1);
@@ -174,9 +193,10 @@
 
     @Override
     protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
-        if (!KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) {
+        if (!ACCEPTED_SIGNING_SCHEMES.contains(key.getAlgorithm().toLowerCase())) {
             throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm()
-                    + ". Only" + KeyProperties.KEY_ALGORITHM_EC + " supported");
+                    + ". Only" + Arrays.toString(ACCEPTED_SIGNING_SCHEMES.stream().toArray())
+                    + " supported");
         }
 
         long keySizeBits = -1;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java
new file mode 100644
index 0000000..4855ad0
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.Authorization;
+import android.system.keystore2.KeyDescriptor;
+
+import java.security.PrivateKey;
+import java.security.interfaces.EdECKey;
+import java.security.spec.NamedParameterSpec;
+
+/**
+ * EdEC private key (instance of {@link PrivateKey} and {@link EdECKey}) backed by keystore.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreEdECPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey {
+    public AndroidKeyStoreEdECPrivateKey(
+            @NonNull KeyDescriptor descriptor, long keyId,
+            @NonNull Authorization[] authorizations,
+            @NonNull String algorithm,
+            @NonNull KeyStoreSecurityLevel securityLevel) {
+        super(descriptor, keyId, authorizations, algorithm, securityLevel);
+    }
+
+    @Override
+    public NamedParameterSpec getParams() {
+        return NamedParameterSpec.ED25519;
+    }
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java
new file mode 100644
index 0000000..642e088
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyMetadata;
+
+import java.math.BigInteger;
+import java.security.interfaces.EdECPublicKey;
+import java.security.spec.EdECPoint;
+import java.security.spec.NamedParameterSpec;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * {@link EdECPublicKey} backed by keystore.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreEdECPublicKey extends AndroidKeyStorePublicKey
+        implements EdECPublicKey {
+    /**
+     * DER sequence, as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-4 and
+     * https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.
+     * SEQUENCE (2 elem)
+     *  SEQUENCE (1 elem)
+     *    OBJECT IDENTIFIER 1.3.101.112 curveEd25519 (EdDSA 25519 signature algorithm)
+     *    as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-3
+     *  BIT STRING (256 bit) as defined in
+     *  https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2
+     */
+    private static final byte[] DER_KEY_PREFIX = new byte[] {
+            0x30,
+            0x2a,
+            0x30,
+            0x05,
+            0x06,
+            0x03,
+            0x2b,
+            0x65,
+            0x70,
+            0x03,
+            0x21,
+            0x00,
+    };
+    private static final int ED25519_KEY_SIZE_BYTES = 32;
+
+    private byte[] mEncodedKey;
+    private EdECPoint mPoint;
+
+    public AndroidKeyStoreEdECPublicKey(
+            @NonNull KeyDescriptor descriptor,
+            @NonNull KeyMetadata metadata,
+            @NonNull String algorithm,
+            @NonNull KeyStoreSecurityLevel iSecurityLevel,
+            @NonNull byte[] encodedKey) {
+        super(descriptor, metadata, encodedKey, algorithm, iSecurityLevel);
+        mEncodedKey = encodedKey;
+
+        int preambleLength = matchesPreamble(DER_KEY_PREFIX, encodedKey);
+        if (preambleLength == 0) {
+            throw new IllegalArgumentException("Key size is not correct size");
+        }
+
+        mPoint = pointFromKeyByteArray(
+                Arrays.copyOfRange(encodedKey, preambleLength, encodedKey.length));
+    }
+
+    @Override
+    AndroidKeyStorePrivateKey getPrivateKey() {
+        return new AndroidKeyStoreEdECPrivateKey(
+                getUserKeyDescriptor(),
+                getKeyIdDescriptor().nspace,
+                getAuthorizations(),
+                "EdDSA",
+                getSecurityLevel());
+    }
+
+    @Override
+    public NamedParameterSpec getParams() {
+        return NamedParameterSpec.ED25519;
+    }
+
+    @Override
+    public EdECPoint getPoint() {
+        return mPoint;
+    }
+
+    private static int matchesPreamble(byte[] preamble, byte[] encoded) {
+        if (encoded.length != (preamble.length + ED25519_KEY_SIZE_BYTES)) {
+            return 0;
+        }
+        if (Arrays.compare(preamble, Arrays.copyOf(encoded, preamble.length)) != 0) {
+            return 0;
+        }
+        return preamble.length;
+    }
+
+    private static EdECPoint pointFromKeyByteArray(byte[] coordinates) {
+        Objects.requireNonNull(coordinates);
+
+        // Oddity of the key is the most-significant bit of the last byte.
+        boolean isOdd = (0x80 & coordinates[coordinates.length - 1]) != 0;
+        // Zero out the oddity bit.
+        coordinates[coordinates.length - 1] &= (byte) 0x7f;
+        // Representation of Y is in little-endian, according to rfc8032 section-3.1.
+        reverse(coordinates);
+        // The integer representing Y starts from the first bit in the coordinates array.
+        BigInteger y = new BigInteger(1, coordinates);
+        return new EdECPoint(isOdd, y);
+    }
+
+    private static void reverse(byte[] coordinateArray) {
+        int start = 0;
+        int end = coordinateArray.length - 1;
+        while (start < end) {
+            byte tmp = coordinateArray[start];
+            coordinateArray[start] = coordinateArray[end];
+            coordinateArray[end] = tmp;
+            start++;
+            end--;
+        }
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return mEncodedKey.clone();
+    }
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
index fc963a8..b1338d1 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
@@ -61,6 +61,17 @@
         }
     }
 
+    /**
+     * X25519 key agreement support.
+     *
+     * @hide
+     */
+    public static class XDH extends AndroidKeyStoreKeyAgreementSpi {
+        public XDH() {
+            super(Algorithm.EC);
+        }
+    }
+
     private final int mKeymintAlgorithm;
 
     // Fields below are populated by engineInit and should be preserved after engineDoFinal.
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 5950b5b..cdc1085 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.security.GenerateRkpKey;
+import android.security.IGenerateRkpKeyService;
 import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStore2;
 import android.security.KeyStoreException;
@@ -624,7 +625,7 @@
              * GenerateRkpKey.notifyEmpty() will delay for a while before returning.
              */
             result = generateKeyPairHelper();
-            if (result.rkpStatus == KeyStoreException.RKP_SUCCESS) {
+            if (result.rkpStatus == KeyStoreException.RKP_SUCCESS && result.keyPair != null) {
                 return result.keyPair;
             }
         }
@@ -706,27 +707,12 @@
             success = true;
             KeyPair kp = new KeyPair(publicKey, publicKey.getPrivateKey());
             return new GenerateKeyPairHelperResult(0, kp);
-        } catch (android.security.KeyStoreException e) {
+        } catch (KeyStoreException e) {
             switch (e.getErrorCode()) {
                 case KeymasterDefs.KM_ERROR_HARDWARE_TYPE_UNAVAILABLE:
                     throw new StrongBoxUnavailableException("Failed to generated key pair.", e);
                 case ResponseCode.OUT_OF_KEYS:
-                    GenerateRkpKey keyGen = new GenerateRkpKey(ActivityThread
-                            .currentApplication());
-                    try {
-                        //TODO: When detailed error information is available from the remote
-                        //provisioner, propagate it up.
-                        keyGen.notifyEmpty(securityLevel);
-                    } catch (RemoteException f) {
-                        KeyStoreException ksException = new KeyStoreException(
-                                ResponseCode.OUT_OF_KEYS,
-                                "Remote exception: " + f.getMessage(),
-                                KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE);
-                        throw new ProviderException("Failed to talk to RemoteProvisioner",
-                                ksException);
-                    }
-                    return new GenerateKeyPairHelperResult(
-                            KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE, null);
+                    return checkIfRetryableOrThrow(e, securityLevel);
                 default:
                     ProviderException p = new ProviderException("Failed to generate key pair.", e);
                     if ((mSpec.getPurposes() & KeyProperties.PURPOSE_WRAP_KEY) != 0) {
@@ -752,6 +738,55 @@
         }
     }
 
+    // In case keystore reports OUT_OF_KEYS, call this handler in an attempt to remotely provision
+    // some keys.
+    GenerateKeyPairHelperResult checkIfRetryableOrThrow(KeyStoreException e, int securityLevel) {
+        GenerateRkpKey keyGen = new GenerateRkpKey(ActivityThread
+                .currentApplication());
+        KeyStoreException ksException;
+        try {
+            final int keyGenStatus = keyGen.notifyEmpty(securityLevel);
+            // Default stance: temporary error. This is a hint to the caller to try again with
+            // exponential back-off.
+            int rkpStatus;
+            switch (keyGenStatus) {
+                case IGenerateRkpKeyService.Status.NO_NETWORK_CONNECTIVITY:
+                    rkpStatus = KeyStoreException.RKP_FETCHING_PENDING_CONNECTIVITY;
+                    break;
+                case IGenerateRkpKeyService.Status.DEVICE_NOT_REGISTERED:
+                    rkpStatus = KeyStoreException.RKP_SERVER_REFUSED_ISSUANCE;
+                    break;
+                case IGenerateRkpKeyService.Status.OK:
+                    // Explicitly return not-OK here so we retry in generateKeyPair. All other cases
+                    // should throw because a retry doesn't make sense if we didn't actually
+                    // provision fresh keys.
+                    return new GenerateKeyPairHelperResult(
+                            KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE, null);
+                case IGenerateRkpKeyService.Status.NETWORK_COMMUNICATION_ERROR:
+                case IGenerateRkpKeyService.Status.HTTP_CLIENT_ERROR:
+                case IGenerateRkpKeyService.Status.HTTP_SERVER_ERROR:
+                case IGenerateRkpKeyService.Status.HTTP_UNKNOWN_ERROR:
+                case IGenerateRkpKeyService.Status.INTERNAL_ERROR:
+                default:
+                    // These errors really should never happen. The best we can do is assume they
+                    // are transient and hint to the caller to retry with back-off.
+                    rkpStatus = KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE;
+                    break;
+            }
+            ksException = new KeyStoreException(
+                    ResponseCode.OUT_OF_KEYS,
+                    "Out of RKP keys due to IGenerateRkpKeyService status: " + keyGenStatus,
+                    rkpStatus);
+        } catch (RemoteException f) {
+            ksException = new KeyStoreException(
+                    ResponseCode.OUT_OF_KEYS,
+                    "Remote exception: " + f.getMessage(),
+                    KeyStoreException.RKP_TEMPORARILY_UNAVAILABLE);
+        }
+        ksException.initCause(e);
+        throw new ProviderException("Failed to provision new attestation keys.", ksException);
+    }
+
     private void addAttestationParameters(@NonNull List<KeyParameter> params)
             throws ProviderException, IllegalArgumentException, DeviceIdAttestationException {
         byte[] challenge = mSpec.getAttestationChallenge();
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index d31499e..9947d34 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -104,6 +104,7 @@
 
         // javax.crypto.KeyAgreement
         put("KeyAgreement.ECDH", PACKAGE_NAME + ".AndroidKeyStoreKeyAgreementSpi$ECDH");
+        put("KeyAgreement.XDH", PACKAGE_NAME + ".AndroidKeyStoreKeyAgreementSpi$XDH");
 
         // java.security.SecretKeyFactory
         putSecretKeyFactoryImpl("AES");
@@ -224,7 +225,6 @@
 
         String jcaKeyAlgorithm = publicKey.getAlgorithm();
 
-        KeyStoreSecurityLevel securityLevel = iSecurityLevel;
         if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
             return new AndroidKeyStoreECPublicKey(descriptor, metadata,
                     iSecurityLevel, (ECPublicKey) publicKey);
@@ -232,11 +232,12 @@
             return new AndroidKeyStoreRSAPublicKey(descriptor, metadata,
                     iSecurityLevel, (RSAPublicKey) publicKey);
         } else if (ED25519_OID.equalsIgnoreCase(jcaKeyAlgorithm)) {
-            //TODO(b/214203951) missing classes in conscrypt
-            throw new ProviderException("Curve " + ED25519_OID + " not supported yet");
+            final byte[] publicKeyEncoded = publicKey.getEncoded();
+            return new AndroidKeyStoreEdECPublicKey(descriptor, metadata, ED25519_OID,
+                    iSecurityLevel, publicKeyEncoded);
         } else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) {
-            //TODO(b/214203951) missing classes in conscrypt
-            throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet");
+            return new AndroidKeyStoreXDHPublicKey(descriptor, metadata, X25519_ALIAS,
+                    iSecurityLevel, publicKey.getEncoded());
         } else {
             throw new ProviderException("Unsupported Android Keystore public key algorithm: "
                     + jcaKeyAlgorithm);
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java
new file mode 100644
index 0000000..42589640
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.Authorization;
+import android.system.keystore2.KeyDescriptor;
+
+import java.security.PrivateKey;
+import java.security.interfaces.EdECKey;
+import java.security.spec.NamedParameterSpec;
+
+/**
+ * X25519 Private Key backed by Keystore.
+ * instance of {@link PrivateKey} and {@link EdECKey}
+ *
+ * @hide
+ */
+public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey {
+    public AndroidKeyStoreXDHPrivateKey(
+            @NonNull KeyDescriptor descriptor, long keyId,
+            @NonNull Authorization[] authorizations,
+            @NonNull String algorithm,
+            @NonNull KeyStoreSecurityLevel securityLevel) {
+        super(descriptor, keyId, authorizations, algorithm, securityLevel);
+    }
+
+    @Override
+    public NamedParameterSpec getParams() {
+        return NamedParameterSpec.X25519;
+    }
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java
new file mode 100644
index 0000000..9f3df3d
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyMetadata;
+
+import java.math.BigInteger;
+import java.security.interfaces.XECPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.NamedParameterSpec;
+import java.util.Arrays;
+
+/**
+ * {@link XECPublicKey} backed by keystore.
+ * This class re-implements Conscrypt's OpenSSLX25519PublicKey. The reason is that
+ * OpenSSLX25519PublicKey does not implement XECPublicKey and is not a part of Conscrypt's public
+ * interface so it cannot be referred to.
+ *
+ * So the functionality is duplicated here until (likely Android U) one of the things mentioned
+ * above is fixed.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreXDHPublicKey extends AndroidKeyStorePublicKey implements XECPublicKey {
+    private static final byte[] X509_PREAMBLE = new byte[] {
+            0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x03, 0x21, 0x00,
+    };
+
+    private static final byte[] X509_PREAMBLE_WITH_NULL = new byte[] {
+            0x30, 0x2C, 0x30, 0x07, 0x06, 0x03, 0x2B, 0x65, 0x6E, 0x05, 0x00, 0x03, 0x21, 0x00,
+    };
+
+    private static final int X25519_KEY_SIZE_BYTES = 32;
+
+    private final byte[] mEncodedKey;
+    private final int mPreambleLength;
+
+    public AndroidKeyStoreXDHPublicKey(
+            @NonNull KeyDescriptor descriptor,
+            @NonNull KeyMetadata metadata,
+            @NonNull String algorithm,
+            @NonNull KeyStoreSecurityLevel iSecurityLevel,
+            @NonNull byte[] encodedKey) {
+        super(descriptor, metadata, encodedKey, algorithm, iSecurityLevel);
+        mEncodedKey = encodedKey;
+        if (mEncodedKey == null) {
+            throw new IllegalArgumentException("empty encoded key.");
+        }
+
+        mPreambleLength = matchesPreamble(X509_PREAMBLE, mEncodedKey) | matchesPreamble(
+                X509_PREAMBLE_WITH_NULL, mEncodedKey);
+        if (mPreambleLength == 0) {
+            throw new IllegalArgumentException("Key size is not correct size");
+        }
+    }
+
+    private static int matchesPreamble(byte[] preamble, byte[] encoded) {
+        if (encoded.length != (preamble.length + X25519_KEY_SIZE_BYTES)) {
+            return 0;
+        }
+
+        if (Arrays.compare(preamble, 0, preamble.length, encoded, 0, preamble.length) != 0) {
+            return 0;
+        }
+        return preamble.length;
+    }
+
+    @Override
+    AndroidKeyStorePrivateKey getPrivateKey() {
+        return new AndroidKeyStoreXDHPrivateKey(
+                getUserKeyDescriptor(),
+                getKeyIdDescriptor().nspace,
+                getAuthorizations(),
+                "x25519",
+                getSecurityLevel());
+    }
+
+    @Override
+    public BigInteger getU() {
+        return new BigInteger(Arrays.copyOfRange(mEncodedKey, mPreambleLength, mEncodedKey.length));
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return mEncodedKey.clone();
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return "XDH";
+    }
+
+    @Override
+    public String getFormat() {
+        return "x.509";
+    }
+
+    @Override
+    public AlgorithmParameterSpec getParams() {
+        return NamedParameterSpec.X25519;
+    }
+}
+
diff --git a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java
new file mode 100644
index 0000000..5bd5797
--- /dev/null
+++ b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.Authorization;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyMetadata;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.math.BigInteger;
+import java.util.Base64;
+
+@RunWith(AndroidJUnit4.class)
+public class AndroidKeyStoreEdECPublicKeyTest {
+    private static KeyDescriptor descriptor() {
+        final KeyDescriptor keyDescriptor = new KeyDescriptor();
+        keyDescriptor.alias = "key";
+        keyDescriptor.blob = null;
+        keyDescriptor.domain = Domain.APP;
+        keyDescriptor.nspace = -1;
+        return keyDescriptor;
+    }
+
+    private static KeyMetadata metadata(byte[] cert, byte[] certChain) {
+        KeyMetadata metadata = new KeyMetadata();
+        metadata.authorizations = new Authorization[0];
+        metadata.certificate = cert;
+        metadata.certificateChain = certChain;
+        metadata.key = descriptor();
+        metadata.modificationTimeMs = 0;
+        metadata.keySecurityLevel = 1;
+        return metadata;
+    }
+
+    @Mock
+    private KeyStoreSecurityLevel mKeystoreSecurityLevel;
+
+    private static class EdECTestVector {
+        public final byte[] encodedKeyBytes;
+        public final boolean isOdd;
+        public final BigInteger yValue;
+
+        EdECTestVector(String b64KeyBytes, boolean isOdd, String yValue) {
+            this.encodedKeyBytes = Base64.getDecoder().decode(b64KeyBytes);
+            this.isOdd = isOdd;
+            this.yValue = new BigInteger(yValue);
+        }
+    }
+
+    private static final EdECTestVector[] ED_EC_TEST_VECTORS = new EdECTestVector[]{
+            new EdECTestVector("MCowBQYDK2VwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo=",
+                    false,
+                    "19147682157189290216699341180089409126316261024914226007941553249095116672780"
+                    ),
+            new EdECTestVector("MCowBQYDK2VwAyEA/0E1IRNzGj85Ot/TPeXqifkqTkdk4voleH0hIq59D9w=",
+                    true,
+                    "41640152188550647350742178040529506688513911269563908889464821205156322689535"
+                    ),
+            new EdECTestVector("MCowBQYDK2VwAyEAunOvGuenetl9GQSXGVo5L3RIr4OOIpFIv/Zre8qTc/8=",
+                    true,
+                    "57647939198144376128225770417635248407428273266444593100194116168980378907578"
+                    ),
+            new EdECTestVector("MCowBQYDK2VwAyEA2hHqaZ5IolswN1Yd58Y4hzhmUMCCqc4PW5A/SFLmTX8=",
+                    false,
+                    "57581368614046789120409806291852629847774713088410311752049592044694364885466"
+                    ),
+    };
+
+    @Test
+    public void testParsingOfValidKeys() {
+        for (EdECTestVector testVector : ED_EC_TEST_VECTORS) {
+            AndroidKeyStoreEdECPublicKey pkey = new AndroidKeyStoreEdECPublicKey(descriptor(),
+                    metadata(null, null), "EdDSA", mKeystoreSecurityLevel,
+                    testVector.encodedKeyBytes);
+
+            assertEquals(pkey.getPoint().isXOdd(), testVector.isOdd);
+            assertEquals(pkey.getPoint().getY(), testVector.yValue);
+        }
+    }
+
+    @Test
+    public void testFailedParsingOfKeysWithDifferentOid() {
+        final byte[] testVectorWithIncorrectOid = Base64.getDecoder().decode(
+                "MCowBQYDLGVwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo=");
+        assertThrows("OID should be unrecognized", IllegalArgumentException.class,
+                () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA",
+                        mKeystoreSecurityLevel, testVectorWithIncorrectOid));
+    }
+
+    @Test
+    public void testFailedParsingOfKeysWithWrongSize() {
+        final byte[] testVectorWithIncorrectKeySize = Base64.getDecoder().decode(
+        "MCwwBQYDK2VwAyMADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSrOzg==");
+        assertThrows("Key length should be invalid", IllegalArgumentException.class,
+                () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA",
+                        mKeystoreSecurityLevel, testVectorWithIncorrectKeySize));
+    }
+}
+
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 72dd2bd..3dc927c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2282,10 +2282,6 @@
      */
     public final void start() {
         native_start();
-        synchronized(mBufferLock) {
-            cacheBuffers(true /* input */);
-            cacheBuffers(false /* input */);
-        }
     }
     private native final void native_start();
 
@@ -3917,6 +3913,9 @@
                         + "objects and attach to QueueRequest objects.");
             }
             if (mCachedInputBuffers == null) {
+                cacheBuffers(true /* input */);
+            }
+            if (mCachedInputBuffers == null) {
                 throw new IllegalStateException();
             }
             // FIXME: check codec status
@@ -3955,6 +3954,9 @@
                         + "Please use getOutputFrame to get output frames.");
             }
             if (mCachedOutputBuffers == null) {
+                cacheBuffers(false /* input */);
+            }
+            if (mCachedOutputBuffers == null) {
                 throw new IllegalStateException();
             }
             // FIXME: check codec status
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 522b021..66e2c41 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -230,9 +230,10 @@
     /**
      * A key describing the log session ID for MediaCodec. The log session ID is a random 32-byte
      * hexadecimal string that is used to associate metrics from multiple media codec instances
-     * to the same playback or recording session.
+     * to the same playback or recording session. The value is created as
+     * {@link android.media.metrics.LogSessionId LogSessionId}. Sessions are created in
+     * {@link android.media.metrics.MediaMetricsManager MediaMetricsManager}.
      * The associated value is a string.
-     * @hide
      */
     public static final String LOG_SESSION_ID = "log-session-id";
 
@@ -1147,7 +1148,7 @@
      * A key describing the per-frame average block QP (Quantization Parameter).
      * This is a part of a video 'Encoding Statistics' export feature.
      * This value is emitted from video encoder for a video frame.
-     * The average value is rounded down (using floor()) to integer value.
+     * The average value is rounded to the nearest integer value.
      *
      * The associated value is an integer.
      */
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index f694482..2c5bdbb 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -1294,45 +1294,46 @@
     std::string defaultMsg = "Unknown Error";
 
     /* translate OS errors to Java API CryptoException errorCodes (which are positive) */
+    jint jerr = 0;
     switch (err) {
         case ERROR_DRM_NO_LICENSE:
-            err = gCryptoErrorCodes.cryptoErrorNoKey;
+            jerr = gCryptoErrorCodes.cryptoErrorNoKey;
             defaultMsg = "Crypto key not available";
             break;
         case ERROR_DRM_LICENSE_EXPIRED:
-            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
+            jerr = gCryptoErrorCodes.cryptoErrorKeyExpired;
             defaultMsg = "License expired";
             break;
         case ERROR_DRM_RESOURCE_BUSY:
-            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
+            jerr = gCryptoErrorCodes.cryptoErrorResourceBusy;
             defaultMsg = "Resource busy or unavailable";
             break;
         case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
-            err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
+            jerr = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
             defaultMsg = "Required output protections are not active";
             break;
         case ERROR_DRM_SESSION_NOT_OPENED:
-            err = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
+            jerr = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
             defaultMsg = "Attempted to use a closed session";
             break;
         case ERROR_DRM_INSUFFICIENT_SECURITY:
-            err = gCryptoErrorCodes.cryptoErrorInsufficientSecurity;
+            jerr = gCryptoErrorCodes.cryptoErrorInsufficientSecurity;
             defaultMsg = "Required security level is not met";
             break;
         case ERROR_DRM_CANNOT_HANDLE:
-            err = gCryptoErrorCodes.cryptoErrorUnsupportedOperation;
+            jerr = gCryptoErrorCodes.cryptoErrorUnsupportedOperation;
             defaultMsg = "Operation not supported in this configuration";
             break;
         case ERROR_DRM_FRAME_TOO_LARGE:
-            err = gCryptoErrorCodes.cryptoErrorFrameTooLarge;
+            jerr = gCryptoErrorCodes.cryptoErrorFrameTooLarge;
             defaultMsg = "Decrytped frame exceeds size of output buffer";
             break;
         case ERROR_DRM_SESSION_LOST_STATE:
-            err = gCryptoErrorCodes.cryptoErrorLostState;
+            jerr = gCryptoErrorCodes.cryptoErrorLostState;
             defaultMsg = "Session state was lost, open a new session and retry";
             break;
         default:  /* Other negative DRM error codes go out best-effort. */
-            err = MediaErrorToJavaError(err);
+            jerr = MediaErrorToJavaError(err);
             defaultMsg = StrCryptoError(err);
             break;
     }
@@ -1344,7 +1345,7 @@
     jstring msgObj = env->NewStringUTF(msgStr.c_str());
 
     jthrowable exception =
-        (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);
+        (jthrowable)env->NewObject(clazz.get(), constructID, jerr, msgObj);
 
     env->Throw(exception);
 }
diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp
index 0b3f9bb..5435113 100644
--- a/packages/CtsShim/build/Android.bp
+++ b/packages/CtsShim/build/Android.bp
@@ -45,6 +45,10 @@
     jni_libs: ["libshim_jni"],
 
     uses_libs: ["android.test.runner"],
+
+    apex_available: [
+        "com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
+    ],
 }
 
 genrule {
@@ -84,6 +88,7 @@
         "//apex_available:platform",
         "com.android.apex.cts.shim.v1",
         "com.android.apex.cts.shim.v2",
+        "com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
         "com.android.apex.cts.shim.v2_no_hashtree",
         "com.android.apex.cts.shim.v2_legacy",
         "com.android.apex.cts.shim.v2_sdk_target_p",
@@ -159,6 +164,7 @@
         "//apex_available:platform",
         "com.android.apex.cts.shim.v1",
         "com.android.apex.cts.shim.v2",
+        "com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
         "com.android.apex.cts.shim.v2_no_hashtree",
         "com.android.apex.cts.shim.v2_legacy",
         "com.android.apex.cts.shim.v2_sdk_target_p",
diff --git a/packages/CtsShim/build/jni/Android.bp b/packages/CtsShim/build/jni/Android.bp
index ba586db..2dbf2a2 100644
--- a/packages/CtsShim/build/jni/Android.bp
+++ b/packages/CtsShim/build/jni/Android.bp
@@ -32,6 +32,7 @@
         "//apex_available:platform",
         "com.android.apex.cts.shim.v1",
         "com.android.apex.cts.shim.v2",
+        "com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
         "com.android.apex.cts.shim.v2_no_hashtree",
         "com.android.apex.cts.shim.v2_legacy",
         "com.android.apex.cts.shim.v2_sdk_target_p",
diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp
index 4a07d49..2c86201 100644
--- a/packages/SettingsLib/ActionBarShadow/Android.bp
+++ b/packages/SettingsLib/ActionBarShadow/Android.bp
@@ -20,4 +20,8 @@
 
     sdk_version: "system_current",
     min_sdk_version: "28",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/AppPreference/Android.bp b/packages/SettingsLib/AppPreference/Android.bp
index 1817a77..122f606 100644
--- a/packages/SettingsLib/AppPreference/Android.bp
+++ b/packages/SettingsLib/AppPreference/Android.bp
@@ -20,4 +20,8 @@
     ],
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp
index 4f65373..5c5da98 100644
--- a/packages/SettingsLib/BarChartPreference/Android.bp
+++ b/packages/SettingsLib/BarChartPreference/Android.bp
@@ -19,4 +19,8 @@
 
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/HelpUtils/Android.bp b/packages/SettingsLib/HelpUtils/Android.bp
index 5826047..aea51b1 100644
--- a/packages/SettingsLib/HelpUtils/Android.bp
+++ b/packages/SettingsLib/HelpUtils/Android.bp
@@ -19,4 +19,8 @@
 
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/LayoutPreference/Android.bp b/packages/SettingsLib/LayoutPreference/Android.bp
index 8a4e53d..aaffdc9 100644
--- a/packages/SettingsLib/LayoutPreference/Android.bp
+++ b/packages/SettingsLib/LayoutPreference/Android.bp
@@ -14,9 +14,13 @@
     resource_dirs: ["res"],
 
     static_libs: [
-          "androidx.preference_preference",
+        "androidx.preference_preference",
     ],
 
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/ProgressBar/Android.bp b/packages/SettingsLib/ProgressBar/Android.bp
index b5bc8f7..fb3c4e6 100644
--- a/packages/SettingsLib/ProgressBar/Android.bp
+++ b/packages/SettingsLib/ProgressBar/Android.bp
@@ -15,4 +15,8 @@
 
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/RestrictedLockUtils/Android.bp b/packages/SettingsLib/RestrictedLockUtils/Android.bp
index c0623ed..a7dcf8d 100644
--- a/packages/SettingsLib/RestrictedLockUtils/Android.bp
+++ b/packages/SettingsLib/RestrictedLockUtils/Android.bp
@@ -19,4 +19,8 @@
 
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/SearchWidget/Android.bp b/packages/SettingsLib/SearchWidget/Android.bp
index b7367b4..5aaee2a 100644
--- a/packages/SettingsLib/SearchWidget/Android.bp
+++ b/packages/SettingsLib/SearchWidget/Android.bp
@@ -14,4 +14,8 @@
     resource_dirs: ["res"],
     sdk_version: "system_current",
     min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.permission",
+    ],
 }
diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp
index 73459c2..da01f62 100644
--- a/packages/SettingsLib/SettingsTheme/Android.bp
+++ b/packages/SettingsLib/SettingsTheme/Android.bp
@@ -13,13 +13,14 @@
     resource_dirs: ["res"],
 
     static_libs: [
-            "androidx.preference_preference",
-        ],
+        "androidx.preference_preference",
+    ],
 
     sdk_version: "system_current",
     min_sdk_version: "21",
     apex_available: [
         "//apex_available:platform",
         "com.android.cellbroadcast",
+        "com.android.permission",
     ],
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index ca054c7..7a8e5af 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -998,7 +998,6 @@
                         == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET)) {
                     EventLog.writeEvent(0x534e4554, "138529441", -1, "");
                 }
-                mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
             }
         }
     }
@@ -1351,7 +1350,7 @@
     /**
      * Store the member devices that are in the same coordinated set.
      */
-    public void setMemberDevice(CachedBluetoothDevice memberDevice) {
+    public void addMemberDevice(CachedBluetoothDevice memberDevice) {
         mMemberDevices.add(memberDevice);
     }
 
@@ -1368,24 +1367,24 @@
      * device and member devices.
      *
      * @param prevMainDevice the previous Main device, it will be added into the member device set.
-     * @param newMainDevie the new Main device, it will be removed from the member device set.
+     * @param newMainDevice the new Main device, it will be removed from the member device set.
      */
     public void switchMemberDeviceContent(CachedBluetoothDevice prevMainDevice,
-            CachedBluetoothDevice newMainDevie) {
+            CachedBluetoothDevice newMainDevice) {
         // Backup from main device
         final BluetoothDevice tmpDevice = mDevice;
         final short tmpRssi = mRssi;
         final boolean tmpJustDiscovered = mJustDiscovered;
         // Set main device from sub device
-        mDevice = newMainDevie.mDevice;
-        mRssi = newMainDevie.mRssi;
-        mJustDiscovered = newMainDevie.mJustDiscovered;
-        setMemberDevice(prevMainDevice);
-        mMemberDevices.remove(newMainDevie);
+        mDevice = newMainDevice.mDevice;
+        mRssi = newMainDevice.mRssi;
+        mJustDiscovered = newMainDevice.mJustDiscovered;
+        addMemberDevice(prevMainDevice);
+        mMemberDevices.remove(newMainDevice);
         // Set sub device from backup
-        newMainDevie.mDevice = tmpDevice;
-        newMainDevie.mRssi = tmpRssi;
-        newMainDevie.mJustDiscovered = tmpJustDiscovered;
+        newMainDevice.mDevice = tmpDevice;
+        newMainDevice.mRssi = tmpRssi;
+        newMainDevice.mJustDiscovered = tmpJustDiscovered;
         fetchActiveDevices();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index cc56a21..89e10c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -85,7 +85,7 @@
             // Once there is other devices with the same groupId, to add new device as member
             // devices.
             if (CsipDevice != null) {
-                CsipDevice.setMemberDevice(newDevice);
+                CsipDevice.addMemberDevice(newDevice);
                 newDevice.setName(CsipDevice.getName());
                 return true;
             }
@@ -148,7 +148,7 @@
             log("onGroupIdChanged: removed from UI device =" + cachedDevice
                     + ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
 
-            mainDevice.setMemberDevice(cachedDevice);
+            mainDevice.addMemberDevice(cachedDevice);
             mCachedDevices.remove(i);
             mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
             break;
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index e5fd0ba..bbb1ec6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.datetime;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.icu.text.TimeZoneFormat;
@@ -35,6 +36,7 @@
 import com.android.i18n.timezone.CountryTimeZones;
 import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping;
 import com.android.i18n.timezone.TimeZoneFinder;
+import com.android.internal.app.LocaleHelper;
 import com.android.settingslib.R;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -99,7 +101,8 @@
         TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);
         CharSequence gmtText = getGmtOffsetText(tzFormatter, locale, tz, now);
         TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
-        String zoneNameString = getZoneLongName(timeZoneNames, tz, now);
+        String zoneNameString = capitalizeForStandaloneDisplay(
+                locale, getZoneLongName(locale, timeZoneNames, tz, now));
         if (zoneNameString == null) {
             return gmtText;
         }
@@ -108,6 +111,24 @@
         return TextUtils.concat(gmtText, " ", zoneNameString);
     }
 
+    /**
+     * Capitalizes {@code toCapitalize} for standalone display, i.e. in lists. This is intended for
+     * use with "display name" strings from sources like ICU/CLDR which typically capitalize strings
+     * for the inclusion in the middle of sentences. Some locales (such as Polish) do not capitalize
+     * terms like "Coordinated Universal Time" as in English but do capitalize the first letter for
+     * standalone locations like lists, and so must be explicitly capitalized.
+     *
+     * @return the capitalized string, or {@code null} if the argument is null
+     */
+    @Nullable
+    public static String capitalizeForStandaloneDisplay(
+            Locale locale, @Nullable String toCapitalize) {
+        if (TextUtils.isEmpty(toCapitalize)) {
+            return toCapitalize;
+        }
+        return LocaleHelper.toSentenceCase(toCapitalize, locale);
+    }
+
     public static List<Map<String, Object>> getZonesList(Context context) {
         final Locale locale = context.getResources().getConfiguration().locale;
         final Date now = new Date();
@@ -116,7 +137,7 @@
 
         // Work out whether the display names we would show by default would be ambiguous.
         final boolean useExemplarLocationForLocalNames =
-                shouldUseExemplarLocationForLocalNames(data, timeZoneNames);
+                shouldUseExemplarLocationForLocalNames(locale, data, timeZoneNames);
 
         // Generate the list of zone entries to return.
         List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>();
@@ -124,7 +145,7 @@
             TimeZone tz = data.timeZones[i];
             CharSequence gmtOffsetText = data.gmtOffsetTexts[i];
 
-            CharSequence displayName = getTimeZoneDisplayName(data, timeZoneNames,
+            CharSequence displayName = getTimeZoneDisplayName(locale, data, timeZoneNames,
                     useExemplarLocationForLocalNames, tz, data.olsonIdsToDisplay[i]);
             if (TextUtils.isEmpty(displayName)) {
                 displayName = gmtOffsetText;
@@ -181,15 +202,15 @@
         return olsonIds;
     }
 
-    private static boolean shouldUseExemplarLocationForLocalNames(ZoneGetterData data,
-            TimeZoneNames timeZoneNames) {
+    private static boolean shouldUseExemplarLocationForLocalNames(Locale locale,
+            ZoneGetterData data, TimeZoneNames timeZoneNames) {
         final Set<CharSequence> localZoneNames = new HashSet<>();
         final Date now = new Date();
         for (int i = 0; i < data.zoneCount; i++) {
             final String olsonId = data.olsonIdsToDisplay[i];
             if (data.localZoneIds.contains(olsonId)) {
                 final TimeZone tz = data.timeZones[i];
-                CharSequence displayName = getZoneLongName(timeZoneNames, tz, now);
+                CharSequence displayName = getZoneLongName(locale, timeZoneNames, tz, now);
                 if (displayName == null) {
                     displayName = data.gmtOffsetTexts[i];
                 }
@@ -203,7 +224,7 @@
         return false;
     }
 
-    private static CharSequence getTimeZoneDisplayName(ZoneGetterData data,
+    private static CharSequence getTimeZoneDisplayName(Locale locale, ZoneGetterData data,
             TimeZoneNames timeZoneNames, boolean useExemplarLocationForLocalNames, TimeZone tz,
             String olsonId) {
         final Date now = new Date();
@@ -212,7 +233,7 @@
         String displayName;
 
         if (preferLongName) {
-            displayName = getZoneLongName(timeZoneNames, tz, now);
+            displayName = getZoneLongName(locale, timeZoneNames, tz, now);
         } else {
             // Canonicalize the zone ID for ICU. It will only return valid strings for zone IDs
             // that match ICUs zone IDs (which are similar but not guaranteed the same as those
@@ -223,10 +244,11 @@
             if (canonicalZoneId == null) {
                 canonicalZoneId = tz.getID();
             }
-            displayName = timeZoneNames.getExemplarLocationName(canonicalZoneId);
+            displayName = capitalizeForStandaloneDisplay(
+                    locale, timeZoneNames.getExemplarLocationName(canonicalZoneId));
             if (displayName == null || displayName.isEmpty()) {
                 // getZoneExemplarLocation can return null. Fall back to the long name.
-                displayName = getZoneLongName(timeZoneNames, tz, now);
+                displayName = getZoneLongName(locale, timeZoneNames, tz, now);
             }
         }
 
@@ -237,11 +259,13 @@
      * Returns the long name for the timezone for the given locale at the time specified.
      * Can return {@code null}.
      */
-    private static String getZoneLongName(TimeZoneNames names, TimeZone tz, Date now) {
+    private static String getZoneLongName(
+            Locale locale, TimeZoneNames names, TimeZone tz, Date now) {
         final TimeZoneNames.NameType nameType =
                 tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT
                         : TimeZoneNames.NameType.LONG_STANDARD;
-        return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime());
+        return capitalizeForStandaloneDisplay(locale,
+                names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime()));
     }
 
     private static String getCanonicalZoneId(TimeZone timeZone) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 298ee90..bef1d9c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -40,7 +40,6 @@
 import org.robolectric.RuntimeEnvironment;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
@@ -503,8 +502,8 @@
         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
         CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3);
-        cachedDevice1.setMemberDevice(cachedDevice2);
-        cachedDevice1.setMemberDevice(cachedDevice3);
+        cachedDevice1.addMemberDevice(cachedDevice2);
+        cachedDevice1.addMemberDevice(cachedDevice3);
 
         assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice2);
         assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice3);
@@ -524,7 +523,7 @@
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
         cachedDevice1.setGroupId(1);
         cachedDevice2.setGroupId(1);
-        cachedDevice1.setMemberDevice(cachedDevice2);
+        cachedDevice1.addMemberDevice(cachedDevice2);
 
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
@@ -541,7 +540,7 @@
         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
         cachedDevice1.setGroupId(1);
         cachedDevice2.setGroupId(1);
-        cachedDevice1.setMemberDevice(cachedDevice2);
+        cachedDevice1.addMemberDevice(cachedDevice2);
 
         // Call onDeviceUnpaired for the one in mCachedDevices.
         mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 208bfbbf..c4d4261 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -478,6 +478,12 @@
     <uses-permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />
     <uses-permission android:name="android.permission.SUGGEST_EXTERNAL_TIME" />
 
+    <!-- Permissions used for manual testing of time detection behavior. -->
+    <uses-permission android:name="android.permission.SUGGEST_MANUAL_TIME" />
+    <uses-permission android:name="android.permission.SUGGEST_TELEPHONY_TIME" />
+    <uses-permission android:name="android.permission.SUGGEST_NETWORK_TIME" />
+    <uses-permission android:name="android.permission.SUGGEST_GNSS_TIME" />
+
     <!-- Permission required for CTS test - android.server.biometrics -->
     <uses-permission android:name="android.permission.USE_BIOMETRIC" />
 
@@ -601,6 +607,7 @@
 
     <!-- Permission required to run the `vm` tool which manages on-device virtual machines -->
     <uses-permission android:name="android.permission.MANAGE_VIRTUAL_MACHINE" />
+    <uses-permission android:name="android.permission.USE_CUSTOM_VIRTUAL_MACHINE" />
     <uses-permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE" />
 
     <!-- Permission required for CTS test - SettingsMultiPaneDeepLinkTest -->
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 6c8a92d..4b07eaf 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -73,6 +73,7 @@
 zakcohen@google.com
 jernej@google.com
 jglazier@google.com
+peskal@google.com
 
 #Android Auto
 hseog@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 9676a57..91c7a24 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -376,7 +376,7 @@
             Log.w(TAG, String.format("onActiveChanged(%d,%d,%s,%s,%d,%d)", code, uid, packageName,
                     Boolean.toString(active), attributionChainId, attributionFlags));
         }
-        if (attributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE
+        if (active && attributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE
                 && attributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE
                 && (attributionFlags & AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR) == 0
                 && (attributionFlags & AppOpsManager.ATTRIBUTION_FLAG_TRUSTED) == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index 40662536..4a3350e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -320,7 +320,7 @@
         info.className = Switch::class.java.name
     }
 
-    override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
+    override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
         if (super.performAccessibilityAction(host, action, args)) {
             return true
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 896f01a..bff56b8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1484,7 +1484,9 @@
     public void doKeyguardTimeout(Bundle options) {
         mHandler.removeMessages(KEYGUARD_TIMEOUT);
         Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
-        mHandler.sendMessage(msg);
+        // Treat these messages with priority - A call to timeout means the device should lock
+        // as soon as possible and not wait for other messages on the thread to process first.
+        mHandler.sendMessageAtFrontOfQueue(msg);
     }
 
     /**
@@ -1665,12 +1667,15 @@
      * @see #handleShow
      */
     private void showLocked(Bundle options) {
-        Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");
+        Trace.beginSection("KeyguardViewMediator#showLocked acquiring mShowKeyguardWakeLock");
         if (DEBUG) Log.d(TAG, "showLocked");
         // ensure we stay awake until we are finished displaying the keyguard
         mShowKeyguardWakeLock.acquire();
         Message msg = mHandler.obtainMessage(SHOW, options);
-        mHandler.sendMessage(msg);
+        // Treat these messages with priority - This call can originate from #doKeyguardTimeout,
+        // meaning the device should lock as soon as possible and not wait for other messages on
+        // the thread to process first.
+        mHandler.sendMessageAtFrontOfQueue(msg);
         Trace.endSection();
     }
 
@@ -1871,6 +1876,7 @@
                 case KEYGUARD_TIMEOUT:
                     synchronized (KeyguardViewMediator.this) {
                         doKeyguardLocked((Bundle) msg.obj);
+                        notifyDefaultDisplayCallbacks(mShowing);
                     }
                     break;
                 case DISMISS:
@@ -2880,7 +2886,7 @@
             for (int i = size - 1; i >= 0; i--) {
                 IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
                 try {
-                    callback.onShowingStateChanged(showing);
+                    callback.onShowingStateChanged(showing, KeyguardUpdateMonitor.getCurrentUser());
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Failed to call onShowingStateChanged", e);
                     if (e instanceof DeadObjectException) {
@@ -2914,7 +2920,7 @@
             mKeyguardStateCallbacks.add(callback);
             try {
                 callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
-                callback.onShowingStateChanged(mShowing);
+                callback.onShowingStateChanged(mShowing, KeyguardUpdateMonitor.getCurrentUser());
                 callback.onInputRestrictedStateChanged(mInputRestricted);
                 callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust(
                         KeyguardUpdateMonitor.getCurrentUser()));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 1225813..67985b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -21,7 +21,7 @@
 import android.app.IUidObserver
 import android.app.Notification
 import android.app.Notification.CallStyle.CALL_TYPE_ONGOING
-import android.content.Intent
+import android.app.PendingIntent
 import android.util.Log
 import android.view.View
 import androidx.annotation.VisibleForTesting
@@ -98,7 +98,7 @@
                 val newOngoingCallInfo = CallNotificationInfo(
                         entry.sbn.key,
                         entry.sbn.notification.`when`,
-                        entry.sbn.notification.contentIntent?.intent,
+                        entry.sbn.notification.contentIntent,
                         entry.sbn.uid,
                         entry.sbn.notification.extras.getInt(
                                 Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING,
@@ -230,7 +230,6 @@
                     logger.logChipClicked()
                     activityStarter.postStartActivityDismissingKeyguard(
                         intent,
-                        0,
                         ActivityLaunchAnimator.Controller.fromView(
                             backgroundView,
                             InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
@@ -351,7 +350,7 @@
     private data class CallNotificationInfo(
         val key: String,
         val callStartTime: Long,
-        val intent: Intent?,
+        val intent: PendingIntent?,
         val uid: Int,
         /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
         val isOngoing: Boolean,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index b385b7d..45c6be9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -22,7 +22,6 @@
 import android.app.Notification
 import android.app.PendingIntent
 import android.app.Person
-import android.content.Intent
 import android.service.notification.NotificationListenerService.REASON_USER_STOPPED
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -429,6 +428,19 @@
                 .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id)
     }
 
+    /** Regression test for b/212467440. */
+    @Test
+    fun chipClicked_activityStarterTriggeredWithUnmodifiedIntent() {
+        val notifEntry = createOngoingCallNotifEntry()
+        val pendingIntent = notifEntry.sbn.notification.contentIntent
+        notifCollectionListener.onEntryUpdated(notifEntry)
+
+        chipView.performClick()
+
+        // Ensure that the sysui didn't modify the notification's intent -- see b/212467440.
+        verify(mockActivityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any())
+    }
+
     @Test
     fun notifyChipVisibilityChanged_visibleEventLogged() {
         controller.notifyChipVisibilityChanged(true)
@@ -570,7 +582,6 @@
             notificationEntryBuilder.modifyNotification(context).setContentIntent(null)
         } else {
             val contentIntent = mock(PendingIntent::class.java)
-            `when`(contentIntent.intent).thenReturn(mock(Intent::class.java))
             notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent)
         }
 
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
index a1c79ef..3109cd8 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -104,7 +104,7 @@
      * @param opt LaunchOptions for clipping
      */
     public void forEachSrc(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
-        blend(1, ain, aout, null);
+        blend(1, ain, aout, opt);
     }
 
     /**
@@ -641,4 +641,3 @@
     }
 */
 }
-
diff --git a/services/core/OWNERS b/services/core/OWNERS
deleted file mode 100644
index 88d0b61..0000000
--- a/services/core/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-per-file Android.bp = file:platform/build/soong:/OWNERS
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index aac1035..296b7bf 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -98,11 +98,13 @@
 
     // example: fs_stat,/dev/block/platform/soc/by-name/userdata,0x5
     private static final String FS_STAT_PATTERN = "fs_stat,[^,]*/([^/,]+),(0x[0-9a-fA-F]+)";
-    private static final int FS_STAT_FS_FIXED = 0x400; // should match with fs_mgr.cpp:FsStatFlags
+    private static final int FS_STAT_FSCK_FS_FIXED =
+            0x400; // should match with fs_mgr.cpp:FsStatFlags
     private static final String FSCK_PASS_PATTERN = "Pass ([1-9]E?):";
     private static final String FSCK_TREE_OPTIMIZATION_PATTERN =
             "Inode [0-9]+ extent tree.*could be shorter";
-    private static final String FSCK_FS_MODIFIED = "FILE SYSTEM WAS MODIFIED";
+    private static final String E2FSCK_FS_MODIFIED = "FILE SYSTEM WAS MODIFIED";
+    private static final String F2FS_FSCK_FS_MODIFIED = "[FSCK] Unreachable";
     // ro.boottime.init.mount_all. + postfix for mount_all duration
     private static final String[] MOUNT_DURATION_PROPS_POSTFIX =
             new String[] { "early", "default", "late" };
@@ -460,9 +462,9 @@
         int lineNumber = 0;
         int lastFsStatLineNumber = 0;
         for (String line : lines) { // should check all lines
-            if (line.contains(FSCK_FS_MODIFIED)) {
+            if (line.contains(E2FSCK_FS_MODIFIED) || line.contains(F2FS_FSCK_FS_MODIFIED)) {
                 uploadNeeded = true;
-            } else if (line.contains("fs_stat")){
+            } else if (line.contains("fs_stat")) {
                 Matcher matcher = pattern.matcher(line);
                 if (matcher.find()) {
                     handleFsckFsStat(matcher, lines, lastFsStatLineNumber, lineNumber);
@@ -474,12 +476,13 @@
             lineNumber++;
         }
 
-        if (uploadEnabled && uploadNeeded ) {
+        if (uploadEnabled && uploadNeeded) {
             addFileToDropBox(db, timestamps, headers, "/dev/fscklogs/log", maxSize, tag);
         }
 
-        // Remove the file so we don't re-upload if the runtime restarts.
-        file.delete();
+        // Rename the file so we don't re-upload if the runtime restarts.
+        File pfile = new File("/dev/fscklogs/fsck");
+        file.renameTo(pfile);
     }
 
     private static void logFsMountTime() {
@@ -673,7 +676,7 @@
     public static int fixFsckFsStat(String partition, int statOrg, String[] lines,
             int startLineNumber, int endLineNumber) {
         int stat = statOrg;
-        if ((stat & FS_STAT_FS_FIXED) != 0) {
+        if ((stat & FS_STAT_FSCK_FS_FIXED) != 0) {
             // fs was fixed. should check if quota warning was caused by tree optimization.
             // This is not a real fix but optimization, so should not be counted as a fs fix.
             Pattern passPattern = Pattern.compile(FSCK_PASS_PATTERN);
@@ -686,7 +689,8 @@
             String otherFixLine = null;
             for (int i = startLineNumber; i < endLineNumber; i++) {
                 String line = lines[i];
-                if (line.contains(FSCK_FS_MODIFIED)) { // no need to parse above this
+                if (line.contains(E2FSCK_FS_MODIFIED)
+                        || line.contains(F2FS_FSCK_FS_MODIFIED)) { // no need to parse above this
                     break;
                 } else if (line.startsWith("Pass ")) {
                     Matcher matcher = passPattern.matcher(line);
@@ -714,9 +718,9 @@
                     }
                 } else if (line.startsWith("Update quota info") && currentPass.equals("5")) {
                     // follows "[QUOTA WARNING]", ignore
-                } else if (line.startsWith("Timestamp(s) on inode") &&
-                        line.contains("beyond 2310-04-04 are likely pre-1970") &&
-                        currentPass.equals("1")) {
+                } else if (line.startsWith("Timestamp(s) on inode")
+                        && line.contains("beyond 2310-04-04 are likely pre-1970")
+                        && currentPass.equals("1")) {
                     Slog.i(TAG, "fs_stat, partition:" + partition + " found timestamp adjustment:"
                             + line);
                     // followed by next line, "Fix? yes"
@@ -744,7 +748,7 @@
             } else if ((foundTreeOptimization && foundQuotaFix) || foundTimestampAdjustment) {
                 // not a real fix, so clear it.
                 Slog.i(TAG, "fs_stat, partition:" + partition + " fix ignored");
-                stat &= ~FS_STAT_FS_FIXED;
+                stat &= ~FS_STAT_FSCK_FS_FIXED;
             }
         }
         return stat;
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 99e12a8..ce0e69c 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -91,6 +91,10 @@
                 if (!volume.isMountedWritable()) {
                     continue;
                 }
+                // gsid only supports vfat external storage.
+                if (!"vfat".equalsIgnoreCase(volume.fsType)) {
+                    continue;
+                }
                 DiskInfo disk = volume.getDisk();
                 long mega = disk.size >> 20;
                 Slog.i(TAG, volume.getPath() + ": " + mega + " MB");
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 06b3311..2bb3952 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -3059,14 +3059,32 @@
         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
         intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId);
         intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
+
         // Send the broadcast twice -- once for all apps with READ_PHONE_STATE, then again
-        // for all apps with READ_PRIV but not READ_PHONE_STATE. This ensures that any app holding
-        // either READ_PRIV or READ_PHONE get this broadcast exactly once.
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE);
-        mContext.createContextAsUser(UserHandle.ALL, 0)
-                .sendBroadcastMultiplePermissions(intent,
-                        new String[] { Manifest.permission.READ_PRIVILEGED_PHONE_STATE },
-                        new String[] { Manifest.permission.READ_PHONE_STATE });
+        // for all apps with READ_PRIVILEGED_PHONE_STATE but not READ_PHONE_STATE.
+        // Do this again twice, the first time for apps with ACCESS_FINE_LOCATION, then again with
+        // the location-sanitized service state for all apps without ACCESS_FINE_LOCATION.
+        // This ensures that any app holding either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE
+        // get this broadcast exactly once, and we are not exposing location without permission.
+        mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(intent,
+                new String[] {Manifest.permission.READ_PHONE_STATE,
+                        Manifest.permission.ACCESS_FINE_LOCATION});
+        mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(intent,
+                new String[] {Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+                        Manifest.permission.ACCESS_FINE_LOCATION},
+                new String[] {Manifest.permission.READ_PHONE_STATE});
+
+        // Replace bundle with location-sanitized ServiceState
+        data = new Bundle();
+        state.createLocationInfoSanitizedCopy(true).fillInNotifierBundle(data);
+        intent.putExtras(data);
+        mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(intent,
+                new String[] {Manifest.permission.READ_PHONE_STATE},
+                new String[] {Manifest.permission.ACCESS_FINE_LOCATION});
+        mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(intent,
+                new String[] {Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
+                new String[] {Manifest.permission.READ_PHONE_STATE,
+                        Manifest.permission.ACCESS_FINE_LOCATION});
     }
 
     private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId,
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 81627a0..2ab477f 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -1803,7 +1803,10 @@
             mComputedNightMode = false;
             return;
         }
-        resetNightModeOverrideLocked();
+        if (mNightMode != MODE_NIGHT_AUTO || (mTwilightManager != null
+                && mTwilightManager.getLastTwilightState() != null)) {
+            resetNightModeOverrideLocked();
+        }
     }
 
     private boolean resetNightModeOverrideLocked() {
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index c1d8e7b..d3ef6be 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -880,6 +880,38 @@
         }
     }
 
+    @Override
+    public boolean setAppExclusionList(int userId, String vpnPackage, List<String> excludedApps) {
+        enforceSettingsPermission();
+        enforceCrossUserPermission(userId);
+
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(userId);
+            if (vpn != null) {
+                return vpn.setAppExclusionList(vpnPackage, excludedApps);
+            } else {
+                logw("User " + userId + " has no Vpn configuration");
+                throw new IllegalStateException(
+                        "VPN for user " + userId + " not ready yet. Skipping setting the list");
+            }
+        }
+    }
+
+    @Override
+    public List<String> getAppExclusionList(int userId, String vpnPackage) {
+        enforceSettingsPermission();
+        enforceCrossUserPermission(userId);
+
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(userId);
+            if (vpn != null) {
+                return vpn.getAppExclusionList(vpnPackage);
+            } else {
+                logw("User " + userId + " has no Vpn configuration");
+                return null;
+            }
+        }
+    }
 
     @Override
     public void factoryReset() {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ab2147d..d0503f3 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -168,8 +168,8 @@
         }
 
         @Override
-        public void onUserStopping(@NonNull TargetUser user) {
-            Slog.i(TAG, "onStopUser " + user);
+        public void onUserStopped(@NonNull TargetUser user) {
+            Slog.i(TAG, "onUserStopped " + user);
             mService.purgeUserData(user.getUserIdentifier());
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ec9f1fe..fd109ff 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -91,7 +91,6 @@
 import static android.os.Process.myPid;
 import static android.os.Process.myUid;
 import static android.os.Process.readProcFile;
-import static android.os.Process.removeAllProcessGroups;
 import static android.os.Process.sendSignal;
 import static android.os.Process.setThreadPriority;
 import static android.os.Process.setThreadScheduler;
@@ -2388,8 +2387,6 @@
     }
 
     private void start() {
-        removeAllProcessGroups();
-
         mBatteryStatsService.publish();
         mAppOpsService.publish();
         Slog.d("AppOps", "AppOpsService published");
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index dc80c4b..1257f1f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2425,8 +2425,8 @@
             if (!regularZygote) {
                 // webview and app zygote don't have the permission to create the nodes
                 if (Process.createProcessGroup(uid, startResult.pid) < 0) {
-                    Slog.e(ActivityManagerService.TAG, "Unable to create process group for "
-                            + app.processName + " (" + startResult.pid + ")");
+                    throw new AssertionError("Unable to create process group for " + app.processName
+                            + " (" + startResult.pid + ")");
                 }
             }
 
@@ -2897,6 +2897,15 @@
         }
 
         int N = procs.size();
+        for (int i = 0; i < N; ++i) {
+            final ProcessRecord proc = procs.get(i).first;
+            try {
+                Process.setProcessFrozen(proc.getPid(), proc.uid, true);
+            } catch (Exception e) {
+                Slog.w(TAG, "Unable to freeze " + proc.getPid() + " " + proc.processName);
+            }
+        }
+
         for (int i=0; i<N; i++) {
             final Pair<ProcessRecord, Boolean> proc = procs.get(i);
             removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index c5ac390..2143be1 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -86,6 +86,7 @@
         DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS,
         DeviceConfig.NAMESPACE_LMKD_NATIVE,
         DeviceConfig.NAMESPACE_MEDIA_NATIVE,
+        DeviceConfig.NAMESPACE_MGLRU_NATIVE,
         DeviceConfig.NAMESPACE_NETD_NATIVE,
         DeviceConfig.NAMESPACE_NNAPI_NATIVE,
         DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
@@ -237,7 +238,7 @@
             }
             value = "";
         } else if (value.length() > SYSTEM_PROPERTY_MAX_LENGTH) {
-            log(value + " exceeds system property max length.");
+            log("key=" + key + " value=" + value + " exceeds system property max length.");
             return;
         }
 
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 406ff9b..a81699f 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1202,8 +1202,11 @@
                     break;
                 case MSG_L_SET_BT_ACTIVE_DEVICE:
                     synchronized (mDeviceStateLock) {
-                        mDeviceInventory.onSetBtActiveDevice((BtDeviceInfo) msg.obj,
-                                mAudioService.getBluetoothContextualVolumeStream());
+                        BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
+                        mDeviceInventory.onSetBtActiveDevice(btInfo,
+                                (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput)
+                                        ? mAudioService.getBluetoothContextualVolumeStream()
+                                        : AudioSystem.STREAM_DEFAULT);
                     }
                     break;
                 case MSG_BT_HEADSET_CNCT_FAILED:
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index dadf2a4..1cc0443 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -10619,7 +10619,7 @@
                 }
             }
             return pids;
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             return new HashSet<Integer>();
         }
     }
diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
index 28c7cad..ab3b250 100644
--- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
+++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.content.ClipData;
+import android.os.PersistableBundle;
 import android.os.SystemProperties;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -25,6 +26,7 @@
 import android.system.VmSocketAddress;
 import android.util.Slog;
 
+import java.io.EOFException;
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
 import java.net.SocketException;
@@ -58,11 +60,11 @@
         return mPipe;
     }
 
-    private synchronized boolean openPipe() {
-        if (mPipe != null) {
-            return true;
-        }
+    private synchronized void setPipeFD(final FileDescriptor fd) {
+        mPipe = fd;
+    }
 
+    private static FileDescriptor openPipeImpl() {
         try {
             final FileDescriptor fd = Os.socket(OsConstants.AF_VSOCK, OsConstants.SOCK_STREAM, 0);
 
@@ -70,39 +72,42 @@
                 Os.connect(fd, new VmSocketAddress(HOST_PORT, OsConstants.VMADDR_CID_HOST));
 
                 final byte[] handshake = createOpenHandshake();
-                Os.write(fd, handshake, 0, handshake.length);
-                mPipe = fd;
-                return true;
+                writeFully(fd, handshake, 0, handshake.length);
+                return fd;
             } catch (ErrnoException | SocketException | InterruptedIOException e) {
                 Os.close(fd);
             }
         } catch (ErrnoException e) {
         }
 
-        return false;
+        return null;
     }
 
-    private synchronized void closePipe() {
-        try {
-            final FileDescriptor fd = mPipe;
-            mPipe = null;
-            if (fd != null) {
-                Os.close(fd);
-            }
-        } catch (ErrnoException ignore) {
+    private static FileDescriptor openPipe() throws InterruptedException {
+        FileDescriptor fd = openPipeImpl();
+
+        // There's no guarantee that QEMU pipes will be ready at the moment
+        // this method is invoked. We simply try to get the pipe open and
+        // retry on failure indefinitely.
+        while (fd == null) {
+            Thread.sleep(100);
+            fd = openPipeImpl();
         }
+
+        return fd;
     }
 
-    private byte[] receiveMessage() throws ErrnoException, InterruptedIOException {
+    private static byte[] receiveMessage(final FileDescriptor fd) throws ErrnoException,
+            InterruptedIOException, EOFException {
         final byte[] lengthBits = new byte[4];
-        Os.read(mPipe, lengthBits, 0, lengthBits.length);
+        readFully(fd, lengthBits, 0, lengthBits.length);
 
         final ByteBuffer bb = ByteBuffer.wrap(lengthBits);
         bb.order(ByteOrder.LITTLE_ENDIAN);
         final int msgLen = bb.getInt();
 
         final byte[] msg = new byte[msgLen];
-        Os.read(mPipe, msg, 0, msg.length);
+        readFully(fd, msg, 0, msg.length);
 
         return msg;
     }
@@ -115,35 +120,46 @@
         bb.order(ByteOrder.LITTLE_ENDIAN);
         bb.putInt(msg.length);
 
-        Os.write(fd, lengthBits, 0, lengthBits.length);
-        Os.write(fd, msg, 0, msg.length);
+        writeFully(fd, lengthBits, 0, lengthBits.length);
+        writeFully(fd, msg, 0, msg.length);
     }
 
     EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) {
         this.mHostMonitorThread = new Thread(() -> {
+            FileDescriptor fd = null;
+
             while (!Thread.interrupted()) {
                 try {
-                    // There's no guarantee that QEMU pipes will be ready at the moment
-                    // this method is invoked. We simply try to get the pipe open and
-                    // retry on failure indefinitely.
-                    while (!openPipe()) {
-                        Thread.sleep(100);
+                    if (fd == null) {
+                        fd = openPipe();
+                        setPipeFD(fd);
                     }
 
-                    final byte[] receivedData = receiveMessage();
+                    final byte[] receivedData = receiveMessage(fd);
 
                     final String str = new String(receivedData);
                     final ClipData clip = new ClipData("host clipboard",
                                                        new String[]{"text/plain"},
                                                        new ClipData.Item(str));
+                    final PersistableBundle bundle = new PersistableBundle();
+                    bundle.putBoolean("com.android.systemui.SUPPRESS_CLIPBOARD_OVERLAY", true);
+                    clip.getDescription().setExtras(bundle);
 
                     if (LOG_CLIBOARD_ACCESS) {
                         Slog.i(TAG, "Setting the guest clipboard to '" + str + "'");
                     }
                     setAndroidClipboard.accept(clip);
-                } catch (ErrnoException | InterruptedIOException e) {
-                    closePipe();
-                } catch (InterruptedException | IllegalArgumentException e) {
+                } catch (ErrnoException | EOFException | InterruptedIOException
+                         | InterruptedException e) {
+                    setPipeFD(null);
+
+                    try {
+                        Os.close(fd);
+                    } catch (ErrnoException e2) {
+                        // ignore
+                    }
+
+                    fd = null;
                 }
             }
         });
@@ -153,33 +169,70 @@
 
     @Override
     public void accept(final @Nullable ClipData clip) {
+        final FileDescriptor fd = getPipeFD();
+        if (fd != null) {
+            setHostClipboard(fd, getClipString(clip));
+        }
+    }
+
+    private String getClipString(final @Nullable ClipData clip) {
         if (clip == null) {
-            setHostClipboardImpl("");
-        } else if (clip.getItemCount() > 0) {
-            final CharSequence text = clip.getItemAt(0).getText();
-            if (text != null) {
-                setHostClipboardImpl(text.toString());
+            return "";
+        }
+
+        if (clip.getItemCount() == 0) {
+            return "";
+        }
+
+        final CharSequence text = clip.getItemAt(0).getText();
+        if (text == null) {
+            return "";
+        }
+
+        return text.toString();
+    }
+
+    private static void setHostClipboard(final FileDescriptor fd, final String value) {
+        Thread t = new Thread(() -> {
+            if (LOG_CLIBOARD_ACCESS) {
+                Slog.i(TAG, "Setting the host clipboard to '" + value + "'");
+            }
+
+            try {
+                sendMessage(fd, value.getBytes());
+            } catch (ErrnoException | InterruptedIOException e) {
+                Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
+            } catch (IllegalArgumentException e) {
+            }
+        });
+        t.start();
+    }
+
+    private static void readFully(final FileDescriptor fd,
+                                  final byte[] buf, int offset, int size)
+                                  throws ErrnoException, InterruptedIOException, EOFException {
+        while (size > 0) {
+            final int r = Os.read(fd, buf, offset, size);
+            if (r > 0) {
+                offset += r;
+                size -= r;
+            } else {
+                throw new EOFException();
             }
         }
     }
 
-    private void setHostClipboardImpl(final String value) {
-        final FileDescriptor pipeFD = getPipeFD();
-
-        if (pipeFD != null) {
-            Thread t = new Thread(() -> {
-                if (LOG_CLIBOARD_ACCESS) {
-                    Slog.i(TAG, "Setting the host clipboard to '" + value + "'");
-                }
-
-                try {
-                    sendMessage(pipeFD, value.getBytes());
-                } catch (ErrnoException | InterruptedIOException e) {
-                    Slog.e(TAG, "Failed to set host clipboard " + e.getMessage());
-                } catch (IllegalArgumentException e) {
-                }
-            });
-            t.start();
+    private static void writeFully(final FileDescriptor fd,
+                                   final byte[] buf, int offset, int size)
+                                   throws ErrnoException, InterruptedIOException {
+        while (size > 0) {
+            final int r = Os.write(fd, buf, offset, size);
+            if (r > 0) {
+                offset += r;
+                size -= r;
+            } else {
+                throw new ErrnoException("write", OsConstants.EIO);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index c53a9a6..e78347b 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -27,6 +27,8 @@
 import static android.os.PowerWhitelistManager.REASON_VPN;
 import static android.os.UserHandle.PER_USER_RANGE;
 
+import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
+
 import static java.util.Objects.requireNonNull;
 
 import android.Manifest;
@@ -84,9 +86,14 @@
 import android.net.ipsec.ike.ChildSessionParams;
 import android.net.ipsec.ike.IkeSession;
 import android.net.ipsec.ike.IkeSessionCallback;
+import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
+import android.net.ipsec.ike.exceptions.IkeNetworkLostException;
+import android.net.ipsec.ike.exceptions.IkeNonProtocolException;
 import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.ipsec.ike.exceptions.IkeTimeoutException;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
@@ -97,6 +104,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -122,11 +130,13 @@
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.net.module.util.NetdUtils;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
 import com.android.server.net.BaseNetworkObserver;
+import com.android.server.vcn.util.PersistableBundleUtils;
 
 import libcore.io.IoUtils;
 
@@ -160,9 +170,10 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -174,6 +185,8 @@
     private static final String VPN_PROVIDER_NAME_BASE = "VpnNetworkProvider:";
     private static final boolean LOGD = true;
     private static final String ANDROID_KEYSTORE_PROVIDER = "AndroidKeyStore";
+    /** Key containing prefix of vpn app excluded list */
+    @VisibleForTesting static final String VPN_APP_EXCLUDED = "VPN_APP_EXCLUDED_";
 
     // Length of time (in milliseconds) that an app hosting an always-on VPN is placed on
     // the device idle allowlist during service launch and VPN bootstrap.
@@ -207,9 +220,10 @@
     private final Context mUserIdContext;
     @VisibleForTesting final Dependencies mDeps;
     private final NetworkInfo mNetworkInfo;
+    @GuardedBy("this")
     private int mLegacyState;
+    @GuardedBy("this")
     @VisibleForTesting protected String mPackage;
-    private String mSessionKey;
     private int mOwnerUID;
     private boolean mIsPackageTargetingAtLeastQ;
     @VisibleForTesting
@@ -246,6 +260,7 @@
      * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
      * only applies to {@link VpnService} connections.
      */
+    @GuardedBy("this")
     @VisibleForTesting protected boolean mAlwaysOn = false;
 
     /**
@@ -253,6 +268,7 @@
      * apps can still bypass by choosing explicit networks. Has no effect if {@link mAlwaysOn} is
      * not set. Applies to all types of VPNs.
      */
+    @GuardedBy("this")
     @VisibleForTesting protected boolean mLockdown = false;
 
     /**
@@ -605,7 +621,7 @@
     }
 
     /** Returns the package name that is currently prepared. */
-    public String getPackage() {
+    public synchronized String getPackage() {
         return mPackage;
     }
 
@@ -686,6 +702,36 @@
         return true;
     }
 
+    private boolean sendEventToVpnManagerApp(@NonNull String category, int errorClass,
+            int errorCode, @NonNull final String packageName, @Nullable final String sessionKey,
+            @NonNull final VpnProfileState profileState, @Nullable final Network underlyingNetwork,
+            @Nullable final NetworkCapabilities nc, @Nullable final LinkProperties lp) {
+        final Intent intent = new Intent(VpnManager.ACTION_VPN_MANAGER_EVENT);
+        intent.setPackage(packageName);
+        intent.addCategory(category);
+        intent.putExtra(VpnManager.EXTRA_VPN_PROFILE_STATE, profileState);
+        intent.putExtra(VpnManager.EXTRA_SESSION_KEY, sessionKey);
+        intent.putExtra(VpnManager.EXTRA_UNDERLYING_NETWORK, underlyingNetwork);
+        intent.putExtra(VpnManager.EXTRA_UNDERLYING_NETWORK_CAPABILITIES, nc);
+        intent.putExtra(VpnManager.EXTRA_UNDERLYING_LINK_PROPERTIES, lp);
+        intent.putExtra(VpnManager.EXTRA_TIMESTAMP_MILLIS, System.currentTimeMillis());
+        if (!VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER.equals(category)
+                || !VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED.equals(category)) {
+            intent.putExtra(VpnManager.EXTRA_ERROR_CLASS, errorClass);
+            intent.putExtra(VpnManager.EXTRA_ERROR_CODE, errorCode);
+        }
+        try {
+            return mUserIdContext.startService(intent) != null;
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Service of VpnManager app " + intent + " failed to start", e);
+            return false;
+        }
+    }
+
+    private boolean isVpnApp(String packageName) {
+        return packageName != null && !VpnConfig.LEGACY_VPN.equals(packageName);
+    }
+
     /**
      * Configures an always-on VPN connection through a specific application. This connection is
      * automatically granted and persisted after a reboot.
@@ -708,12 +754,48 @@
             boolean lockdown,
             @Nullable List<String> lockdownAllowlist) {
         enforceControlPermissionOrInternalCaller();
+        // Store mPackage since it might be reset or might be replaced with the other VPN app.
+        final String oldPackage = mPackage;
+        final boolean isPackageChanged = !Objects.equals(packageName, oldPackage);
+        // TODO: Remove "SdkLevel.isAtLeastT()" check once VpnManagerService is decoupled from
+        //  ConnectivityServiceTest.
+        // Only notify VPN apps that were already always-on, and only if the always-on provider
+        // changed, or the lockdown mode changed.
+        final boolean shouldNotifyOldPkg = isVpnApp(oldPackage) && mAlwaysOn
+                && (lockdown != mLockdown || isPackageChanged);
+        // Also notify the new package if there was a provider change.
+        final boolean shouldNotifyNewPkg = isVpnApp(packageName) && isPackageChanged;
 
-        if (setAlwaysOnPackageInternal(packageName, lockdown, lockdownAllowlist)) {
-            saveAlwaysOnPackage();
+        if (!setAlwaysOnPackageInternal(packageName, lockdown, lockdownAllowlist)) {
+            return false;
+        }
+
+        saveAlwaysOnPackage();
+
+        // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
+        //  ConnectivityServiceTest.
+        if (!SdkLevel.isAtLeastT()) {
             return true;
         }
-        return false;
+
+        if (shouldNotifyOldPkg) {
+            // If both of shouldNotifyOldPkg & isPackageChanged are true, that means the
+            // always-on of old package is disabled or the old package is replaced with the new
+            // package. In this case, VpnProfileState should be disconnected.
+            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED,
+                    -1 /* errorClass */, -1 /* errorCode*/, oldPackage,
+                    null /* sessionKey */, isPackageChanged ? makeDisconnectedVpnProfileState()
+                            : makeVpnProfileStateLocked(),
+                    null /* underlyingNetwork */, null /* nc */, null /* lp */);
+        }
+
+        if (shouldNotifyNewPkg) {
+            sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED,
+                    -1 /* errorClass */, -1 /* errorCode*/, packageName,
+                    getSessionKeyLocked(), makeVpnProfileStateLocked(),
+                    null /* underlyingNetwork */, null /* nc */, null /* lp */);
+        }
+        return true;
     }
 
     /**
@@ -1007,6 +1089,7 @@
         return true;
     }
 
+    @GuardedBy("this")
     private boolean isCurrentPreparedPackage(String packageName) {
         // We can't just check that packageName matches mPackage, because if the app was uninstalled
         // and reinstalled it will no longer be prepared. Similarly if there is a shared UID, the
@@ -1044,6 +1127,17 @@
                 if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
                     mAppOpsManager.finishOp(
                             AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
+                    // The underlying network, NetworkCapabilities and LinkProperties are not
+                    // necessary to send to VPN app since the purpose of this event is to notify
+                    // VPN app that VPN is deactivated by the user.
+                    // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
+                    //  ConnectivityServiceTest.
+                    if (SdkLevel.isAtLeastT()) {
+                        sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
+                                -1 /* errorClass */, -1 /* errorCode*/, mPackage,
+                                getSessionKeyLocked(), makeVpnProfileStateLocked(),
+                                null /* underlyingNetwork */, null /* nc */, null /* lp */);
+                    }
                 }
                 // cleanupVpnStateLocked() is called from mVpnRunner.exit()
                 mVpnRunner.exit();
@@ -1300,6 +1394,7 @@
         return true;
     }
 
+    @GuardedBy("this")
     private void agentConnect() {
         LinkProperties lp = makeLinkProperties();
 
@@ -1534,11 +1629,19 @@
     }
 
     // Note: Return type guarantees results are deduped and sorted, which callers require.
+    // This method also adds the SDK sandbox UIDs corresponding to the applications by default,
+    // since apps are generally not aware of them, yet they should follow the VPN configuration
+    // of the app they belong to.
     private SortedSet<Integer> getAppsUids(List<String> packageNames, int userId) {
         SortedSet<Integer> uids = new TreeSet<>();
         for (String app : packageNames) {
             int uid = getAppUid(app, userId);
             if (uid != -1) uids.add(uid);
+            // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
+            // ConnectivityServiceTest.
+            if (Process.isApplicationUid(uid) && SdkLevel.isAtLeastT()) {
+                uids.add(Process.toSdkSandboxUid(uid));
+            }
         }
         return uids;
     }
@@ -1991,11 +2094,10 @@
     public synchronized int getActiveVpnType() {
         if (!mNetworkInfo.isConnectedOrConnecting()) return VpnManager.TYPE_VPN_NONE;
         if (mVpnRunner == null) return VpnManager.TYPE_VPN_SERVICE;
-        return mVpnRunner instanceof IkeV2VpnRunner
-                ? VpnManager.TYPE_VPN_PLATFORM
-                : VpnManager.TYPE_VPN_LEGACY;
+        return isIkev2VpnRunner() ? VpnManager.TYPE_VPN_PLATFORM : VpnManager.TYPE_VPN_LEGACY;
     }
 
+    @GuardedBy("this")
     private void updateAlwaysOnNotification(DetailedState networkState) {
         final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
 
@@ -2434,6 +2536,21 @@
         }
     }
 
+    @Nullable
+    protected synchronized NetworkCapabilities getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+            NetworkCapabilities nc) {
+        if (nc == null) return null;
+        return mConnectivityManager.getRedactedNetworkCapabilitiesForPackage(
+                nc, mOwnerUID, mPackage);
+    }
+
+    @Nullable
+    protected synchronized LinkProperties getRedactedLinkPropertiesOfUnderlyingNetwork(
+            LinkProperties lp) {
+        if (lp == null) return null;
+        return mConnectivityManager.getRedactedLinkPropertiesForPackage(lp, mOwnerUID, mPackage);
+    }
+
     /** This class represents the common interface for all VPN runners. */
     @VisibleForTesting
     abstract class VpnRunner extends Thread {
@@ -2468,13 +2585,27 @@
     interface IkeV2VpnRunnerCallback {
         void onDefaultNetworkChanged(@NonNull Network network);
 
-        void onChildOpened(
-                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig);
+        void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc);
 
-        void onChildTransformCreated(
-                @NonNull Network network, @NonNull IpSecTransform transform, int direction);
+        void onDefaultNetworkLinkPropertiesChanged(@NonNull LinkProperties lp);
 
-        void onSessionLost(@NonNull Network network, @Nullable Exception exception);
+        void onDefaultNetworkLost(@NonNull Network network);
+
+        void onIkeOpened(int token, @NonNull IkeSessionConfiguration ikeConfiguration);
+
+        void onIkeConnectionInfoChanged(
+                int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo);
+
+        void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig);
+
+        void onChildTransformCreated(int token, @NonNull IpSecTransform transform, int direction);
+
+        void onChildMigrated(
+                int token,
+                @NonNull IpSecTransform inTransform,
+                @NonNull IpSecTransform outTransform);
+
+        void onSessionLost(int token, @Nullable Exception exception);
     }
 
     /**
@@ -2505,6 +2636,10 @@
     class IkeV2VpnRunner extends VpnRunner implements IkeV2VpnRunnerCallback {
         @NonNull private static final String TAG = "IkeV2VpnRunner";
 
+        // 5 seconds grace period before tearing down the IKE Session in case new default network
+        // will come up
+        private static final long NETWORK_LOST_TIMEOUT_MS = 5000L;
+
         @NonNull private final IpSecManager mIpSecManager;
         @NonNull private final Ikev2VpnProfile mProfile;
         @NonNull private final ConnectivityManager.NetworkCallback mNetworkCallback;
@@ -2516,21 +2651,51 @@
          * of the mutable Ikev2VpnRunner fields. The Ikev2VpnRunner is built mostly lock-free by
          * virtue of everything being serialized on this executor.
          */
-        @NonNull private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+        @NonNull
+        private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1);
+
+        @Nullable private ScheduledFuture<?> mScheduledHandleNetworkLostTimeout;
 
         /** Signal to ensure shutdown is honored even if a new Network is connected. */
         private boolean mIsRunning = true;
 
+        /**
+         * The token used by the primary/current/active IKE session.
+         *
+         * <p>This token MUST be updated when the VPN switches to use a new IKE session.
+         */
+        private int mCurrentToken = -1;
+
         @Nullable private IpSecTunnelInterface mTunnelIface;
-        @Nullable private IkeSession mSession;
         @Nullable private Network mActiveNetwork;
+        @Nullable private NetworkCapabilities mUnderlyingNetworkCapabilities;
+        @Nullable private LinkProperties mUnderlyingLinkProperties;
+        private final String mSessionKey;
+
+        @Nullable private IkeSession mSession;
+        @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo;
+
+        // mMobikeEnabled can only be updated after IKE AUTH is finished.
+        private boolean mMobikeEnabled = false;
 
         IkeV2VpnRunner(@NonNull Ikev2VpnProfile profile) {
             super(TAG);
             mProfile = profile;
             mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this);
+            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
             mSessionKey = UUID.randomUUID().toString();
+
+            // Set the policy so that cancelled tasks will be removed from the work queue
+            mExecutor.setRemoveOnCancelPolicy(true);
+
+            // Set the policy so that all delayed tasks will not be executed
+            mExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+
+            // To avoid hitting RejectedExecutionException upon shutdown of the mExecutor */
+            mExecutor.setRejectedExecutionHandler(
+                    (r, executor) -> {
+                        Log.d(TAG, "Runnable " + r + " rejected by the mExecutor");
+                    });
         }
 
         @Override
@@ -2569,22 +2734,63 @@
             return Objects.equals(mActiveNetwork, network) && mIsRunning;
         }
 
+        private boolean isActiveToken(int token) {
+            return (mCurrentToken == token) && mIsRunning;
+        }
+
+        /**
+         * Called when an IKE session has been opened
+         *
+         * <p>This method is only ever called once per IkeSession, and MUST run on the mExecutor
+         * thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         */
+        public void onIkeOpened(int token, @NonNull IkeSessionConfiguration ikeConfiguration) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onIkeOpened called for obsolete token " + token);
+                return;
+            }
+
+            mMobikeEnabled =
+                    ikeConfiguration.isIkeExtensionEnabled(
+                            IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE);
+            onIkeConnectionInfoChanged(token, ikeConfiguration.getIkeSessionConnectionInfo());
+        }
+
+        /**
+         * Called when an IKE session's {@link IkeSessionConnectionInfo} is available or updated
+         *
+         * <p>This callback is usually fired when an IKE session has been opened or migrated.
+         *
+         * <p>This method is called multiple times over the lifetime of an IkeSession, and MUST run
+         * on the mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         */
+        public void onIkeConnectionInfoChanged(
+                int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onIkeConnectionInfoChanged called for obsolete token " + token);
+                return;
+            }
+
+            // The update on VPN and the IPsec tunnel will be done when migration is fully complete
+            // in onChildMigrated
+            mIkeConnectionInfo = ikeConnectionInfo;
+        }
+
         /**
          * Called when an IKE Child session has been opened, signalling completion of the startup.
          *
          * <p>This method is only ever called once per IkeSession, and MUST run on the mExecutor
          * thread in order to ensure consistency of the Ikev2VpnRunner fields.
          */
-        public void onChildOpened(
-                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "onOpened called for obsolete network " + network);
+        public void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onChildOpened called for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
@@ -2603,6 +2809,11 @@
                     dnsAddrStrings.add(addr.getHostAddress());
                 }
 
+                // The actual network of this IKE session has been set up with is
+                // mIkeConnectionInfo.getNetwork() instead of mActiveNetwork because
+                // mActiveNetwork might have been updated after the setup was triggered.
+                final Network network = mIkeConnectionInfo.getNetwork();
+
                 final NetworkAgent networkAgent;
                 final LinkProperties lp;
 
@@ -2623,6 +2834,8 @@
 
                     mConfig.underlyingNetworks = new Network[] {network};
 
+                    mConfig.disallowedApplications = getAppExclusionList(mPackage);
+
                     networkAgent = mNetworkAgent;
 
                     // The below must be done atomically with the mConfig update, otherwise
@@ -2643,8 +2856,8 @@
 
                 networkAgent.sendLinkProperties(lp);
             } catch (Exception e) {
-                Log.d(TAG, "Error in ChildOpened for network " + network, e);
-                onSessionLost(network, e);
+                Log.d(TAG, "Error in ChildOpened for token " + token, e);
+                onSessionLost(token, e);
             }
         }
 
@@ -2652,19 +2865,19 @@
          * Called when an IPsec transform has been created, and should be applied.
          *
          * <p>This method is called multiple times over the lifetime of an IkeSession (or default
-         * network), and is MUST always be called on the mExecutor thread in order to ensure
+         * network), and MUST always be called on the mExecutor thread in order to ensure
          * consistency of the Ikev2VpnRunner fields.
          */
         public void onChildTransformCreated(
-                @NonNull Network network, @NonNull IpSecTransform transform, int direction) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "ChildTransformCreated for obsolete network " + network);
+                int token, @NonNull IpSecTransform transform, int direction) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "ChildTransformCreated for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
@@ -2673,84 +2886,229 @@
                 // them alive for us
                 mIpSecManager.applyTunnelModeTransform(mTunnelIface, direction, transform);
             } catch (IOException e) {
-                Log.d(TAG, "Transform application failed for network " + network, e);
-                onSessionLost(network, e);
+                Log.d(TAG, "Transform application failed for token " + token, e);
+                onSessionLost(token, e);
+            }
+        }
+
+        /**
+         * Called when an IPsec transform has been created, and should be re-applied.
+         *
+         * <p>This method is called multiple times over the lifetime of an IkeSession (or default
+         * network), and MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
+         */
+        public void onChildMigrated(
+                int token,
+                @NonNull IpSecTransform inTransform,
+                @NonNull IpSecTransform outTransform) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onChildMigrated for obsolete token " + token);
+                return;
+            }
+
+            // The actual network of this IKE session has migrated to is
+            // mIkeConnectionInfo.getNetwork() instead of mActiveNetwork because mActiveNetwork
+            // might have been updated after the migration was triggered.
+            final Network network = mIkeConnectionInfo.getNetwork();
+
+            try {
+                synchronized (Vpn.this) {
+                    mConfig.underlyingNetworks = new Network[] {network};
+                    mNetworkCapabilities =
+                            new NetworkCapabilities.Builder(mNetworkCapabilities)
+                                    .setUnderlyingNetworks(Collections.singletonList(network))
+                                    .build();
+                    mNetworkAgent.setUnderlyingNetworks(Collections.singletonList(network));
+                }
+
+                mTunnelIface.setUnderlyingNetwork(network);
+
+                // Transforms do not need to be persisted; the IkeSession will keep them alive for
+                // us
+                mIpSecManager.applyTunnelModeTransform(
+                        mTunnelIface, IpSecManager.DIRECTION_IN, inTransform);
+                mIpSecManager.applyTunnelModeTransform(
+                        mTunnelIface, IpSecManager.DIRECTION_OUT, outTransform);
+            } catch (IOException e) {
+                Log.d(TAG, "Transform application failed for token " + token, e);
+                onSessionLost(token, e);
             }
         }
 
         /**
          * Called when a new default network is connected.
          *
-         * <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE
-         * state in the process, and starting a new IkeSession instance.
+         * <p>The Ikev2VpnRunner will unconditionally switch to the new network. If the IKE session
+         * has mobility, Ikev2VpnRunner will migrate the existing IkeSession to the new network.
+         * Otherwise, Ikev2VpnRunner will kill the old IKE state, and start a new IkeSession
+         * instance.
          *
-         * <p>This method is called multiple times over the lifetime of the Ikev2VpnRunner, and is
-         * called on the ConnectivityService thread. Thus, the actual work MUST be proxied to the
-         * mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
          */
         public void onDefaultNetworkChanged(@NonNull Network network) {
-            Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network);
+            Log.d(TAG, "onDefaultNetworkChanged: " + network);
 
-            // Proxy to the Ikev2VpnRunner (single-thread) executor to ensure consistency in lieu
-            // of locking.
-            mExecutor.execute(() -> {
-                try {
-                    if (!mIsRunning) {
-                        Log.d(TAG, "onDefaultNetworkChanged after exit");
-                        return; // VPN has been shut down.
-                    }
+            cancelHandleNetworkLostTimeout();
 
-                    // Clear mInterface to prevent Ikev2VpnRunner being cleared when
-                    // interfaceRemoved() is called.
-                    mInterface = null;
-                    // Without MOBIKE, we have no way to seamlessly migrate. Close on old
-                    // (non-default) network, and start the new one.
-                    resetIkeState();
-                    mActiveNetwork = network;
-
-                    // Get Ike options from IkeTunnelConnectionParams if it's available in the
-                    // profile.
-                    final IkeTunnelConnectionParams ikeTunConnParams =
-                            mProfile.getIkeTunnelConnectionParams();
-                    final IkeSessionParams ikeSessionParams;
-                    final ChildSessionParams childSessionParams;
-                    if (ikeTunConnParams != null) {
-                        final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
-                                ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
-                        ikeSessionParams = builder.build();
-                        childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
-                    } else {
-                        ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
-                                mContext, mProfile, network);
-                        childSessionParams = VpnIkev2Utils.buildChildSessionParams(
-                                mProfile.getAllowedAlgorithms());
-                    }
-
-                    // TODO: Remove the need for adding two unused addresses with
-                    // IPsec tunnels.
-                    final InetAddress address = InetAddress.getLocalHost();
-                    mTunnelIface =
-                            mIpSecManager.createIpSecTunnelInterface(
-                                    address /* unused */,
-                                    address /* unused */,
-                                    network);
-                    NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
-
-                    mSession = mIkev2SessionCreator.createIkeSession(
-                            mContext,
-                            ikeSessionParams,
-                            childSessionParams,
-                            mExecutor,
-                            new VpnIkev2Utils.IkeSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network),
-                            new VpnIkev2Utils.ChildSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network));
-                    Log.d(TAG, "Ike Session started for network " + network);
-                } catch (Exception e) {
-                    Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
-                    onSessionLost(network, e);
+            try {
+                if (!mIsRunning) {
+                    Log.d(TAG, "onDefaultNetworkChanged after exit");
+                    return; // VPN has been shut down.
                 }
-            });
+
+                mActiveNetwork = network;
+
+                if (mSession != null && mMobikeEnabled) {
+                    // IKE session can schedule a migration event only when IKE AUTH is finished
+                    // and mMobikeEnabled is true.
+                    Log.d(
+                            TAG,
+                            "Migrate IKE Session with token "
+                                    + mCurrentToken
+                                    + " to network "
+                                    + network);
+                    mSession.setNetwork(network);
+                    return;
+                }
+
+                // Clear mInterface to prevent Ikev2VpnRunner being cleared when
+                // interfaceRemoved() is called.
+                mInterface = null;
+                // Without MOBIKE, we have no way to seamlessly migrate. Close on old
+                // (non-default) network, and start the new one.
+                resetIkeState();
+
+                // Get Ike options from IkeTunnelConnectionParams if it's available in the
+                // profile.
+                final IkeTunnelConnectionParams ikeTunConnParams =
+                        mProfile.getIkeTunnelConnectionParams();
+                final IkeSessionParams ikeSessionParams;
+                final ChildSessionParams childSessionParams;
+                if (ikeTunConnParams != null) {
+                    final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
+                            ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
+                    ikeSessionParams = builder.build();
+                    childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
+                } else {
+                    ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
+                            mContext, mProfile, network);
+                    childSessionParams = VpnIkev2Utils.buildChildSessionParams(
+                            mProfile.getAllowedAlgorithms());
+                }
+
+                // TODO: Remove the need for adding two unused addresses with
+                // IPsec tunnels.
+                final InetAddress address = InetAddress.getLocalHost();
+
+                // When onChildOpened is called and transforms are applied, it is
+                // guaranteed that the underlying network is still "network", because the
+                // all the network switch events will be deferred before onChildOpened is
+                // called. Thus it is safe to build a mTunnelIface before IKE setup.
+                mTunnelIface =
+                        mIpSecManager.createIpSecTunnelInterface(
+                                address /* unused */, address /* unused */, network);
+                NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
+
+                final int token = ++mCurrentToken;
+                mSession =
+                        mIkev2SessionCreator.createIkeSession(
+                                mContext,
+                                ikeSessionParams,
+                                childSessionParams,
+                                mExecutor,
+                                new VpnIkev2Utils.IkeSessionCallbackImpl(
+                                        TAG, IkeV2VpnRunner.this, token),
+                                new VpnIkev2Utils.ChildSessionCallbackImpl(
+                                        TAG, IkeV2VpnRunner.this, token));
+                Log.d(TAG, "IKE session started for token " + token);
+            } catch (Exception e) {
+                Log.i(TAG, "Setup failed for token " + mCurrentToken + ". Aborting", e);
+                onSessionLost(mCurrentToken, e);
+            }
+        }
+
+        /** Called when the NetworkCapabilities of underlying network is changed */
+        public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
+            mUnderlyingNetworkCapabilities = nc;
+        }
+
+        /** Called when the LinkProperties of underlying network is changed */
+        public void onDefaultNetworkLinkPropertiesChanged(@NonNull LinkProperties lp) {
+            mUnderlyingLinkProperties = lp;
+        }
+
+        /**
+         * Handles loss of the default underlying network
+         *
+         * <p>If the IKE Session has mobility, Ikev2VpnRunner will schedule a teardown event with a
+         * delay so that the IKE Session can migrate if a new network is available soon. Otherwise,
+         * Ikev2VpnRunner will kill the IKE session and reset the VPN.
+         *
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
+         */
+        public void onDefaultNetworkLost(@NonNull Network network) {
+            if (!isActiveNetwork(network)) {
+                Log.d(TAG, "onDefaultNetworkLost called for obsolete network " + network);
+
+                // Do nothing; this signals that either: (1) a new/better Network was found,
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
+                return;
+            }
+
+            if (mScheduledHandleNetworkLostTimeout != null
+                    && !mScheduledHandleNetworkLostTimeout.isCancelled()
+                    && !mScheduledHandleNetworkLostTimeout.isDone()) {
+                final IllegalStateException exception =
+                        new IllegalStateException(
+                                "Found a pending mScheduledHandleNetworkLostTimeout");
+                Log.i(
+                        TAG,
+                        "Unexpected error in onDefaultNetworkLost. Tear down session",
+                        exception);
+                handleSessionLost(exception);
+                return;
+            }
+
+            if (mSession != null && mMobikeEnabled) {
+                Log.d(
+                        TAG,
+                        "IKE Session has mobility. Delay handleSessionLost for losing network "
+                                + network
+                                + "on session with token "
+                                + mCurrentToken);
+
+                // Delay the teardown in case a new network will be available soon. For example,
+                // during handover between two WiFi networks, Android will disconnect from the
+                // first WiFi and then connects to the second WiFi.
+                mScheduledHandleNetworkLostTimeout =
+                        mExecutor.schedule(
+                                () -> {
+                                    handleSessionLost(null);
+                                },
+                                NETWORK_LOST_TIMEOUT_MS,
+                                TimeUnit.MILLISECONDS);
+            } else {
+                Log.d(TAG, "Call handleSessionLost for losing network " + network);
+                handleSessionLost(null);
+            }
+        }
+
+        private void cancelHandleNetworkLostTimeout() {
+            if (mScheduledHandleNetworkLostTimeout != null
+                    && !mScheduledHandleNetworkLostTimeout.isDone()) {
+                // It does not matter what to put in #cancel(boolean), because it is impossible
+                // that the task tracked by mScheduledHandleNetworkLostTimeout is
+                // in-progress since both that task and onDefaultNetworkChanged are submitted to
+                // mExecutor who has only one thread.
+                Log.d(TAG, "Cancel the task for handling network lost timeout");
+                mScheduledHandleNetworkLostTimeout.cancel(false /* mayInterruptIfRunning */);
+            }
         }
 
         /** Marks the state as FAILED, and disconnects. */
@@ -2771,44 +3129,99 @@
          * <p>This method MUST always be called on the mExecutor thread in order to ensure
          * consistency of the Ikev2VpnRunner fields.
          */
-        public void onSessionLost(@NonNull Network network, @Nullable Exception exception) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "onSessionLost() called for obsolete network " + network);
+        public void onSessionLost(int token, @Nullable Exception exception) {
+            Log.d(TAG, "onSessionLost() called for token " + token);
+
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onSessionLost() called for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // onSessionLost() and resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
-            if (exception instanceof IkeProtocolException) {
-                final IkeProtocolException ikeException = (IkeProtocolException) exception;
+            handleSessionLost(exception);
+        }
 
-                switch (ikeException.getErrorType()) {
-                    case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough
-                    case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough
-                    case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough
-                    case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough
-                    case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough
-                    case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE:
-                        // All the above failures are configuration errors, and are terminal
-                        markFailedAndDisconnect(exception);
-                        return;
-                    // All other cases possibly recoverable.
+        private void handleSessionLost(@Nullable Exception exception) {
+            // Cancel mScheduledHandleNetworkLostTimeout if the session it is going to terminate is
+            // already terminated due to other failures.
+            cancelHandleNetworkLostTimeout();
+
+            synchronized (Vpn.this) {
+                String category = "";
+                int errorClass = 0;
+                int errorCode = 0;
+                if (exception instanceof IkeProtocolException) {
+                    final IkeProtocolException ikeException = (IkeProtocolException) exception;
+                    category = VpnManager.CATEGORY_EVENT_IKE_ERROR;
+                    errorCode = ikeException.getErrorType();
+
+                    switch (ikeException.getErrorType()) {
+                        case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough
+                        case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough
+                        case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough
+                        case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough
+                        case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough
+                        case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE:
+                            // All the above failures are configuration errors, and are terminal
+                            errorClass = VpnManager.ERROR_CLASS_NOT_RECOVERABLE;
+                            break;
+                        // All other cases possibly recoverable.
+                        default:
+                            // All the above failures are configuration errors, and are terminal
+                            errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
+                    }
+                } else if (exception instanceof IllegalArgumentException) {
+                    // Failed to build IKE/ChildSessionParams; fatal profile configuration error
+                    markFailedAndDisconnect(exception);
+                    return;
+                } else if (exception instanceof IkeNetworkLostException) {
+                    category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
+                    errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
+                    errorCode = VpnManager.ERROR_CODE_NETWORK_LOST;
+                } else if (exception instanceof IkeNonProtocolException) {
+                    category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
+                    errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
+                    if (exception.getCause() instanceof UnknownHostException) {
+                        errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
+                    } else if (exception.getCause() instanceof IkeTimeoutException) {
+                        errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
+                    } else if (exception.getCause() instanceof IOException) {
+                        errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
+                    }
+                } else if (exception != null) {
+                    Log.wtf(TAG, "onSessionLost: exception = " + exception);
                 }
-            } else if (exception instanceof IllegalArgumentException) {
-                // Failed to build IKE/ChildSessionParams; fatal profile configuration error
-                markFailedAndDisconnect(exception);
-                return;
+                // TODO(b/230548427): Remove SDK check once VPN related stuff are
+                //  decoupled from ConnectivityServiceTest.
+                if (SdkLevel.isAtLeastT()) {
+                    sendEventToVpnManagerApp(category, errorClass, errorCode,
+                            getPackage(), mSessionKey, makeVpnProfileStateLocked(),
+                            mActiveNetwork,
+                            getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
+                                    mUnderlyingNetworkCapabilities),
+                            getRedactedLinkPropertiesOfUnderlyingNetwork(
+                                    mUnderlyingLinkProperties));
+                }
+                if (errorClass == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
+                    markFailedAndDisconnect(exception);
+                    return;
+                } else if (errorClass == VpnManager.ERROR_CLASS_RECOVERABLE) {
+                    // Retry a new IKE session.
+                }
             }
 
             mActiveNetwork = null;
+            mUnderlyingNetworkCapabilities = null;
+            mUnderlyingLinkProperties = null;
 
             // Close all obsolete state, but keep VPN alive incase a usable network comes up.
             // (Mirrors VpnService behavior)
-            Log.d(TAG, "Resetting state for network: " + network);
+            Log.d(TAG, "Resetting state for token: " + mCurrentToken);
 
             synchronized (Vpn.this) {
                 // Since this method handles non-fatal errors only, set mInterface to null to
@@ -2853,6 +3266,8 @@
                 mSession.kill(); // Kill here to make sure all resources are released immediately
                 mSession = null;
             }
+            mIkeConnectionInfo = null;
+            mMobikeEnabled = false;
         }
 
         /**
@@ -2869,7 +3284,8 @@
          */
         private void disconnectVpnRunner() {
             mActiveNetwork = null;
-            mSessionKey = null;
+            mUnderlyingNetworkCapabilities = null;
+            mUnderlyingLinkProperties = null;
             mIsRunning = false;
 
             resetIkeState();
@@ -3299,7 +3715,7 @@
     }
 
     private boolean isCurrentIkev2VpnLocked(@NonNull String packageName) {
-        return isCurrentPreparedPackage(packageName) && mVpnRunner instanceof IkeV2VpnRunner;
+        return isCurrentPreparedPackage(packageName) && isIkev2VpnRunner();
     }
 
     /**
@@ -3353,6 +3769,16 @@
         return VpnProfile.decode("" /* Key unused */, encoded);
     }
 
+    private boolean isIkev2VpnRunner() {
+        return (mVpnRunner instanceof IkeV2VpnRunner);
+    }
+
+    @GuardedBy("this")
+    @Nullable
+    private String getSessionKeyLocked() {
+        return isIkev2VpnRunner() ? ((IkeV2VpnRunner) mVpnRunner).mSessionKey : null;
+    }
+
     /**
      * Starts an already provisioned VPN Profile, keyed by package name.
      *
@@ -3380,7 +3806,11 @@
             }
 
             startVpnProfilePrivileged(profile, packageName);
-            return mSessionKey;
+            if (!isIkev2VpnRunner()) {
+                throw new IllegalStateException("mVpnRunner shouldn't be null and should also be "
+                        + "an instance of Ikev2VpnRunner");
+            }
+            return getSessionKeyLocked();
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -3465,6 +3895,88 @@
         }
     }
 
+    private boolean storeAppExclusionList(@NonNull String packageName,
+            @NonNull List<String> excludedApps) {
+        byte[] data;
+        try {
+            final PersistableBundle bundle = PersistableBundleUtils.fromList(
+                    excludedApps, PersistableBundleUtils.STRING_SERIALIZER);
+            data = PersistableBundleUtils.toDiskStableBytes(bundle);
+        } catch (IOException e) {
+            Log.e(TAG, "problem writing into stream", e);
+            return false;
+        }
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            getVpnProfileStore().put(getVpnAppExcludedForPackage(packageName), data);
+        } finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+        return true;
+    }
+
+    @VisibleForTesting
+    String getVpnAppExcludedForPackage(String packageName) {
+        return VPN_APP_EXCLUDED + mUserId + "_" + packageName;
+    }
+
+    /**
+     * Set the application exclusion list for the specified VPN profile.
+     *
+     * @param packageName the package name of the app provisioning this profile
+     * @param excludedApps the list of excluded packages
+     *
+     * @return whether setting the list is successful or not
+     */
+    public synchronized boolean setAppExclusionList(@NonNull String packageName,
+            @NonNull List<String> excludedApps) {
+        enforceNotRestrictedUser();
+        if (!storeAppExclusionList(packageName, excludedApps)) return false;
+        // Re-build and update NetworkCapabilities via NetworkAgent.
+        if (mNetworkAgent != null) {
+            // Only update the platform VPN
+            if (isIkev2VpnRunner()) {
+                mConfig.disallowedApplications = List.copyOf(excludedApps);
+                mNetworkCapabilities = new NetworkCapabilities.Builder(mNetworkCapabilities)
+                        .setUids(createUserAndRestrictedProfilesRanges(
+                                mUserId, null /* allowedApplications */, excludedApps))
+                        .build();
+                mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Gets the application exclusion list for the specified VPN profile.
+     *
+     * @param packageName the package name of the app provisioning this profile
+     * @return the list of excluded packages for the specified VPN profile or empty list if there is
+     *         no provisioned VPN profile.
+     */
+    @NonNull
+    public synchronized List<String> getAppExclusionList(@NonNull String packageName) {
+        enforceNotRestrictedUser();
+
+        final long oldId = Binder.clearCallingIdentity();
+        try {
+            final byte[] bytes = getVpnProfileStore().get(getVpnAppExcludedForPackage(packageName));
+
+            if (bytes == null || bytes.length == 0) return new ArrayList<>();
+
+            final PersistableBundle bundle = PersistableBundleUtils.fromDiskStableBytes(bytes);
+            return PersistableBundleUtils.toList(bundle, STRING_DESERIALIZER);
+        } catch (IOException e) {
+            Log.e(TAG, "problem reading from stream", e);
+        }  finally {
+            Binder.restoreCallingIdentity(oldId);
+        }
+
+        return new ArrayList<>();
+    }
+
     private @VpnProfileState.State int getStateFromLegacyState(int legacyState) {
         switch (legacyState) {
             case LegacyVpnInfo.STATE_CONNECTING:
@@ -3482,12 +3994,17 @@
         }
     }
 
-    private VpnProfileState makeVpnProfileState() {
-        // TODO: mSessionKey will be moved to Ikev2VpnRunner once aosp/2007077 is merged, so after
-        //  merging aosp/2007077, here should check Ikev2VpnRunner is null or not. Session key will
-        //  be null if Ikev2VpnRunner is null.
-        return new VpnProfileState(getStateFromLegacyState(mLegacyState), mSessionKey, mAlwaysOn,
-                mLockdown);
+    @GuardedBy("this")
+    @NonNull
+    private VpnProfileState makeVpnProfileStateLocked() {
+        return new VpnProfileState(getStateFromLegacyState(mLegacyState),
+                isIkev2VpnRunner() ? getSessionKeyLocked() : null, mAlwaysOn, mLockdown);
+    }
+
+    @NonNull
+    private VpnProfileState makeDisconnectedVpnProfileState() {
+        return new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, null /* sessionKey */,
+                false /* alwaysOn */, false /* lockdown */);
     }
 
     /**
@@ -3501,7 +4018,7 @@
             @NonNull String packageName) {
         requireNonNull(packageName, "No package name provided");
         enforceNotRestrictedUser();
-        return isCurrentIkev2VpnLocked(packageName) ? makeVpnProfileState() : null;
+        return isCurrentIkev2VpnLocked(packageName) ? makeVpnProfileStateLocked() : null;
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index a0a596d..857c86d 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -50,7 +50,9 @@
 import android.net.IpPrefix;
 import android.net.IpSecAlgorithm;
 import android.net.IpSecTransform;
+import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.RouteInfo;
 import android.net.eap.EapSessionConfig;
 import android.net.ipsec.ike.ChildSaProposal;
@@ -66,6 +68,7 @@
 import android.net.ipsec.ike.IkeSaProposal;
 import android.net.ipsec.ike.IkeSessionCallback;
 import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTrafficSelector;
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
@@ -86,6 +89,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * Utility class to build and convert IKEv2/IPsec parameters.
@@ -104,6 +108,7 @@
                 new IkeSessionParams.Builder(context)
                         .setServerHostname(profile.getServerAddr())
                         .setNetwork(network)
+                        .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
                         .setLocalIdentification(localId)
                         .setRemoteIdentification(remoteId);
         setIkeAuth(profile, ikeOptionsBuilder);
@@ -295,72 +300,79 @@
     static class IkeSessionCallbackImpl implements IkeSessionCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
-        private final Network mNetwork;
+        private final int mToken;
 
-        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
+        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
             mTag = tag;
             mCallback = callback;
-            mNetwork = network;
+            mToken = token;
         }
 
         @Override
         public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
-            Log.d(mTag, "IkeOpened for network " + mNetwork);
-            // Nothing to do here.
+            Log.d(mTag, "IkeOpened for token " + mToken);
+            mCallback.onIkeOpened(mToken, ikeSessionConfig);
         }
 
         @Override
         public void onClosed() {
-            Log.d(mTag, "IkeClosed for network " + mNetwork);
-            mCallback.onSessionLost(mNetwork, null); // Server requested session closure. Retry?
+            Log.d(mTag, "IkeClosed for token " + mToken);
+            mCallback.onSessionLost(mToken, null); // Server requested session closure. Retry?
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Log.d(mTag, "IkeClosedExceptionally for network " + mNetwork, exception);
-            mCallback.onSessionLost(mNetwork, exception);
+            Log.d(mTag, "IkeClosedExceptionally for token " + mToken, exception);
+            mCallback.onSessionLost(mToken, exception);
         }
 
         @Override
         public void onError(@NonNull IkeProtocolException exception) {
-            Log.d(mTag, "IkeError for network " + mNetwork, exception);
+            Log.d(mTag, "IkeError for token " + mToken, exception);
             // Non-fatal, log and continue.
         }
+
+        @Override
+        public void onIkeSessionConnectionInfoChanged(
+                @NonNull IkeSessionConnectionInfo connectionInfo) {
+            Log.d(mTag, "onIkeSessionConnectionInfoChanged for token " + mToken);
+            mCallback.onIkeConnectionInfoChanged(mToken, connectionInfo);
+        }
     }
 
     static class ChildSessionCallbackImpl implements ChildSessionCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
-        private final Network mNetwork;
+        private final int mToken;
 
-        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
+        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
             mTag = tag;
             mCallback = callback;
-            mNetwork = network;
+            mToken = token;
         }
 
         @Override
         public void onOpened(@NonNull ChildSessionConfiguration childConfig) {
-            Log.d(mTag, "ChildOpened for network " + mNetwork);
-            mCallback.onChildOpened(mNetwork, childConfig);
+            Log.d(mTag, "ChildOpened for token " + mToken);
+            mCallback.onChildOpened(mToken, childConfig);
         }
 
         @Override
         public void onClosed() {
-            Log.d(mTag, "ChildClosed for network " + mNetwork);
-            mCallback.onSessionLost(mNetwork, null);
+            Log.d(mTag, "ChildClosed for token " + mToken);
+            mCallback.onSessionLost(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Log.d(mTag, "ChildClosedExceptionally for network " + mNetwork, exception);
-            mCallback.onSessionLost(mNetwork, exception);
+            Log.d(mTag, "ChildClosedExceptionally for token " + mToken, exception);
+            mCallback.onSessionLost(mToken, exception);
         }
 
         @Override
         public void onIpSecTransformCreated(@NonNull IpSecTransform transform, int direction) {
-            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; network " + mNetwork);
-            mCallback.onChildTransformCreated(mNetwork, transform, direction);
+            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; token " + mToken);
+            mCallback.onChildTransformCreated(mToken, transform, direction);
         }
 
         @Override
@@ -368,30 +380,56 @@
             // Nothing to be done; no references to the IpSecTransform are held by the
             // Ikev2VpnRunner (or this callback class), and this transform will be closed by the
             // IKE library.
-            Log.d(mTag,
-                    "ChildTransformDeleted; Direction: " + direction + "; for network " + mNetwork);
+            Log.d(mTag, "ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
+        }
+
+        @Override
+        public void onIpSecTransformsMigrated(
+                @NonNull IpSecTransform inIpSecTransform,
+                @NonNull IpSecTransform outIpSecTransform) {
+            Log.d(mTag, "ChildTransformsMigrated; token " + mToken);
+            mCallback.onChildMigrated(mToken, inIpSecTransform, outIpSecTransform);
         }
     }
 
     static class Ikev2VpnNetworkCallback extends NetworkCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
+        private final Executor mExecutor;
 
-        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback) {
+        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback,
+                Executor executor) {
             mTag = tag;
             mCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
         public void onAvailable(@NonNull Network network) {
-            Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network);
-            mCallback.onDefaultNetworkChanged(network);
+            Log.d(mTag, "onAvailable called for network: " + network);
+            mExecutor.execute(() -> mCallback.onDefaultNetworkChanged(network));
+        }
+
+        @Override
+        public void onCapabilitiesChanged(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities) {
+            Log.d(mTag, "NC changed for net " + network + " : " + networkCapabilities);
+            mExecutor.execute(
+                    () -> mCallback.onDefaultNetworkCapabilitiesChanged(networkCapabilities));
+        }
+
+        @Override
+        public void onLinkPropertiesChanged(@NonNull Network network,
+                @NonNull LinkProperties linkProperties) {
+            Log.d(mTag, "LP changed for net " + network + " : " + linkProperties);
+            mExecutor.execute(
+                    () -> mCallback.onDefaultNetworkLinkPropertiesChanged(linkProperties));
         }
 
         @Override
         public void onLost(@NonNull Network network) {
-            Log.d(mTag, "Tearing down; lost network: " + network);
-            mCallback.onSessionLost(network, null);
+            Log.d(mTag, "onLost called for network: " + network);
+            mExecutor.execute(() -> mCallback.onDefaultNetworkLost(network));
         }
     }
 
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 2c2a2bf..7d8a22a 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -505,12 +505,36 @@
         }
     }
 
+    // Return the path to the given file, either the new path
+    // /data/system/$filename, or the old path /data/system_de/$filename if the
+    // file exists there but not at the new path.  Only use this for EVENTS_FILE
+    // and AMBIENT_BRIGHTNESS_STATS_FILE.
+    //
+    // Explanation: this service previously incorrectly stored these two files
+    // directly in /data/system_de, instead of in /data/system where they should
+    // have been.  As system_server no longer has write access to
+    // /data/system_de itself, these files were moved to /data/system.  To
+    // lazily migrate the files, we simply read from the old path if it exists
+    // and the new one doesn't, and always write to the new path.  Note that
+    // system_server doesn't have permission to delete the old files.
+    private AtomicFile getFileWithLegacyFallback(String filename) {
+        AtomicFile file = mInjector.getFile(filename);
+        if (file != null && !file.exists()) {
+            AtomicFile legacyFile = mInjector.getLegacyFile(filename);
+            if (legacyFile != null && legacyFile.exists()) {
+                Slog.i(TAG, "Reading " + filename + " from old location");
+                return legacyFile;
+            }
+        }
+        return file;
+    }
+
     private void readEvents() {
         synchronized (mEventsLock) {
             // Read might prune events so mark as dirty.
             mEventsDirty = true;
             mEvents.clear();
-            final AtomicFile readFrom = mInjector.getFile(EVENTS_FILE);
+            final AtomicFile readFrom = getFileWithLegacyFallback(EVENTS_FILE);
             if (readFrom != null && readFrom.exists()) {
                 FileInputStream input = null;
                 try {
@@ -528,7 +552,7 @@
 
     private void readAmbientBrightnessStats() {
         mAmbientBrightnessStatsTracker = new AmbientBrightnessStatsTracker(mUserManager, null);
-        final AtomicFile readFrom = mInjector.getFile(AMBIENT_BRIGHTNESS_STATS_FILE);
+        final AtomicFile readFrom = getFileWithLegacyFallback(AMBIENT_BRIGHTNESS_STATS_FILE);
         if (readFrom != null && readFrom.exists()) {
             FileInputStream input = null;
             try {
@@ -1095,6 +1119,10 @@
         }
 
         public AtomicFile getFile(String filename) {
+            return new AtomicFile(new File(Environment.getDataSystemDirectory(), filename));
+        }
+
+        public AtomicFile getLegacyFile(String filename) {
             return new AtomicFile(new File(Environment.getDataSystemDeDirectory(), filename));
         }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 72b79f4..efecfeb 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -422,7 +422,7 @@
      */
     boolean isConnectedToArcPort(int physicalAddress) {
         int portId = physicalAddressToPortId(physicalAddress);
-        if (portId != Constants.INVALID_PORT_ID) {
+        if (portId != Constants.INVALID_PORT_ID && portId != Constants.CEC_SWITCH_HOME) {
             return mPortInfoMap.get(portId).isArcSupported();
         }
         return false;
diff --git a/services/core/java/com/android/server/input/OWNERS b/services/core/java/com/android/server/input/OWNERS
index 82c6ee1..4c20c4d 100644
--- a/services/core/java/com/android/server/input/OWNERS
+++ b/services/core/java/com/android/server/input/OWNERS
@@ -1,3 +1 @@
-lzye@google.com
-michaelwr@google.com
-svv@google.com
+include /INPUT_OWNERS
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0c47efe..3858d7a 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -174,6 +174,7 @@
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
+import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkIdentity;
@@ -236,6 +237,7 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 import android.util.SparseLongArray;
+import android.util.SparseSetArray;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
@@ -624,6 +626,9 @@
     /** Map from network ID to last observed roaming state */
     @GuardedBy("mNetworkPoliciesSecondLock")
     private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
+    /** Map from network ID to the last ifaces on it */
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private SparseSetArray<String> mNetworkToIfaces = new SparseSetArray<>();
 
     /** Map from netId to subId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
@@ -1343,11 +1348,28 @@
         return changed;
     }
 
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private boolean updateNetworkToIfacesNL(int netId, @NonNull ArraySet<String> newIfaces) {
+        // TODO: Add a facility SparseSetArray.contains(key) to return whether the key exists.
+        final ArraySet<String> lastIfaces = mNetworkToIfaces.get(netId);
+        final boolean changed = lastIfaces == null ? true : !lastIfaces.equals(newIfaces);
+
+        if (changed) {
+            // Changed on the same network should remove last ifaces and add new ifaces.
+            // TODO: Add a facility SparseSetArray.put(key, value) for replacing the
+            //       value for a given key.
+            mNetworkToIfaces.remove(netId);
+            for (String iface : newIfaces) {
+                mNetworkToIfaces.add(netId, iface);
+            }
+        }
+        return changed;
+    }
+
     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
         @Override
-        public void onCapabilitiesChanged(Network network,
-                NetworkCapabilities networkCapabilities) {
-            if (network == null || networkCapabilities == null) return;
+        public void onCapabilitiesChanged(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities) {
 
             synchronized (mNetworkPoliciesSecondLock) {
                 final boolean newMetered = !networkCapabilities
@@ -1366,6 +1388,25 @@
                 }
             }
         }
+
+        @Override
+        public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties lp) {
+            synchronized (mNetworkPoliciesSecondLock) {
+                final ArraySet<String> newIfaces = new ArraySet<>(lp.getAllInterfaceNames());
+                final boolean ifacesChanged = updateNetworkToIfacesNL(network.getNetId(),
+                        newIfaces);
+                if (ifacesChanged) {
+                    updateNetworkRulesNL();
+                }
+            }
+        }
+
+        @Override
+        public void onLost(@NonNull Network network) {
+            synchronized (mNetworkPoliciesSecondLock) {
+                mNetworkToIfaces.remove(network.getNetId());
+            }
+        }
     };
 
     /**
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d9f2e97..bdd6830 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -658,7 +658,14 @@
             return mBuffer.descendingIterator();
         }
 
-        public StatusBarNotification[] getArray(int count, boolean includeSnoozed) {
+        public StatusBarNotification[] getArray(UserManager um, int count, boolean includeSnoozed) {
+            ArrayList<Integer> currentUsers = new ArrayList<>();
+            currentUsers.add(UserHandle.USER_ALL);
+            Binder.withCleanCallingIdentity(() -> {
+                for (int user : um.getProfileIds(ActivityManager.getCurrentUser(), false)) {
+                    currentUsers.add(user);
+                }
+            });
             synchronized (mBufferLock) {
                 if (count == 0) count = mBufferSize;
                 List<StatusBarNotification> a = new ArrayList();
@@ -667,8 +674,10 @@
                 while (iter.hasNext() && i < count) {
                     Pair<StatusBarNotification, Integer> pair = iter.next();
                     if (pair.second != REASON_SNOOZED || includeSnoozed) {
-                        i++;
-                        a.add(pair.first);
+                        if (currentUsers.contains(pair.first.getUserId())) {
+                            i++;
+                            a.add(pair.first);
+                        }
                     }
                 }
                 return a.toArray(new StatusBarNotification[a.size()]);
@@ -4034,22 +4043,32 @@
                     android.Manifest.permission.ACCESS_NOTIFICATIONS,
                     "NotificationManagerService.getActiveNotifications");
 
-            StatusBarNotification[] tmp = null;
+            ArrayList<StatusBarNotification> tmp = new ArrayList<>();
             int uid = Binder.getCallingUid();
 
+            ArrayList<Integer> currentUsers = new ArrayList<>();
+            currentUsers.add(UserHandle.USER_ALL);
+            Binder.withCleanCallingIdentity(() -> {
+                for (int user : mUm.getProfileIds(ActivityManager.getCurrentUser(), false)) {
+                    currentUsers.add(user);
+                }
+            });
+
             // noteOp will check to make sure the callingPkg matches the uid
             if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg,
                     callingAttributionTag, null)
                     == AppOpsManager.MODE_ALLOWED) {
                 synchronized (mNotificationLock) {
-                    tmp = new StatusBarNotification[mNotificationList.size()];
                     final int N = mNotificationList.size();
-                    for (int i=0; i<N; i++) {
-                        tmp[i] = mNotificationList.get(i).getSbn();
+                    for (int i = 0; i < N; i++) {
+                        final StatusBarNotification sbn = mNotificationList.get(i).getSbn();
+                        if (currentUsers.contains(sbn.getUserId())) {
+                            tmp.add(sbn);
+                        }
                     }
                 }
             }
-            return tmp;
+            return tmp.toArray(new StatusBarNotification[tmp.size()]);
         }
 
         /**
@@ -4158,7 +4177,7 @@
                     callingAttributionTag, null)
                     == AppOpsManager.MODE_ALLOWED) {
                 synchronized (mArchive) {
-                    tmp = mArchive.getArray(count, includeSnoozed);
+                    tmp = mArchive.getArray(mUm, count, includeSnoozed);
                 }
             }
             return tmp;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d0e4457..3ddcf17 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -126,6 +126,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.EventLog;
 import android.util.ExceptionUtils;
 import android.util.MathUtils;
 import android.util.Slog;
@@ -3097,6 +3098,11 @@
             if (mResolvedBaseFile == null) {
                 mResolvedBaseFile = new File(appInfo.getBaseCodePath());
                 inheritFileLocked(mResolvedBaseFile);
+            } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
+                EventLog.writeEvent(0x534e4554, "219044664");
+
+                // Installing base.apk. Make sure the app is restarted.
+                params.setDontKillApp(false);
             }
 
             // Inherit splits if not overridden.
@@ -3743,6 +3749,11 @@
     }
 
     @Override
+    public int getInstallFlags() {
+        return params.installFlags;
+    }
+
+    @Override
     public DataLoaderParamsParcel getDataLoaderParams() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
         return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fad18d2..7d1dbc5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13257,7 +13257,8 @@
             // Don't use profiles since that may cause compilation to be skipped.
             final int res = performDexOptInternalWithDependenciesLI(pkg, pkgSetting,
                     new DexoptOptions(packageName,
-                            getDefaultCompilerFilter(),
+                            REASON_CMDLINE,
+                            getDefaultCompilerFilter(), null /* splitName */,
                             DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 5047690..7650d2ef 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -70,9 +70,16 @@
     void prepareUserData(int userId, int userSerial, int flags) {
         synchronized (mInstallLock) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            /*
+             * Internal storage must be prepared before adoptable storage, since the user's volume
+             * keys are stored in their internal storage.
+             */
+            prepareUserDataLI(null /* internal storage */, userId, userSerial, flags, true);
             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
                 final String volumeUuid = vol.getFsUuid();
-                prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
+                if (volumeUuid != null) {
+                    prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
+                }
             }
         }
     }
@@ -133,10 +140,17 @@
     void destroyUserData(int userId, int flags) {
         synchronized (mInstallLock) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            /*
+             * Volume destruction order isn't really important, but to avoid any weird issues we
+             * process internal storage last, the opposite of prepareUserData.
+             */
             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
                 final String volumeUuid = vol.getFsUuid();
-                destroyUserDataLI(volumeUuid, userId, flags);
+                if (volumeUuid != null) {
+                    destroyUserDataLI(volumeUuid, userId, flags);
+                }
             }
+            destroyUserDataLI(null /* internal storage */, userId, flags);
         }
     }
 
@@ -150,14 +164,18 @@
             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
                     FileUtils.deleteContentsAndDir(getUserSystemDirectory(userId));
-                    FileUtils.deleteContentsAndDir(getDataSystemDeDirectory(userId));
+                    // Delete the contents of /data/system_de/$userId, but not the directory itself
+                    // since vold is responsible for that and system_server isn't allowed to do it.
+                    FileUtils.deleteContents(getDataSystemDeDirectory(userId));
                 }
                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
-                    FileUtils.deleteContentsAndDir(getDataSystemCeDirectory(userId));
+                    // Likewise, delete the contents of /data/system_ce/$userId but not the
+                    // directory itself.
+                    FileUtils.deleteContents(getDataSystemCeDirectory(userId));
                 }
             }
 
-            // Data with special labels is now gone, so finish the job
+            // All the user's data directories should be empty now, so finish the job.
             storage.destroyUserStorage(volumeUuid, userId, flags);
 
         } catch (Exception e) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 075275a..be7e2da 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3966,7 +3966,7 @@
         for (int i = 0; i < userSize; i++) {
             final UserData user = mUsers.valueAt(i);
             if (DBG) Slog.d(LOG_TAG, i + ":" + user.info.toFullString());
-            if (user.info.preCreated && user.info.userType.equals(userType)) {
+            if (user.info.preCreated && !user.info.partial && user.info.userType.equals(userType)) {
                 if (!user.info.isInitialized()) {
                     Slog.w(LOG_TAG, "found pre-created user of type " + userType
                             + ", but it's not initialized yet: " + user.info.toFullString());
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 67bc2b2..580ba74 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -790,7 +790,8 @@
                     Intent.CATEGORY_HOME_MAIN, userId);
             grantPermissionsToSystemPackage(pm, wearPackage, userId,
                     CONTACTS_PERMISSIONS, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
-            grantSystemFixedPermissionsToSystemPackage(pm, wearPackage, userId, PHONE_PERMISSIONS);
+            grantSystemFixedPermissionsToSystemPackage(pm, wearPackage, userId, PHONE_PERMISSIONS,
+                                                       ACTIVITY_RECOGNITION_PERMISSIONS);
 
             // Fitness tracking on watches
             if (mContext.getResources().getBoolean(R.bool.config_trackerAppNeedsPermissions)) {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index ac650ec..2029f86 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -195,6 +195,12 @@
 
     @Override // Binder interface
     public void doKeyguardTimeout(Bundle options) {
+        int userId = mKeyguardStateMonitor.getCurrentUser();
+        if (mKeyguardStateMonitor.isSecure(userId)) {
+            // Preemptively inform the cache that the keyguard will soon be showing, as calls to
+            // doKeyguardTimeout are a signal to lock the device as soon as possible.
+            mKeyguardStateMonitor.onShowingStateChanged(true, userId);
+        }
         try {
             mService.doKeyguardTimeout(options);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index e651137..c0aa8ae 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -78,8 +78,14 @@
         return mTrusted;
     }
 
+    public int getCurrentUser() {
+        return mCurrentUserId;
+    }
+
     @Override // Binder interface
-    public void onShowingStateChanged(boolean showing) {
+    public void onShowingStateChanged(boolean showing, int userId) {
+        if (userId != mCurrentUserId) return;
+
         mIsShowing = showing;
 
         mCallback.onShowingChanged();
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index ee0e5ba..e3dcfd0 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -247,6 +247,8 @@
         if (autoGrantPermissions != null && callingPkg != null) {
             // Need to own the Uri to call in with permissions to grant.
             enforceOwner(callingPkg, uri, userId);
+            // b/208232850: Needs to verify caller before granting slice access
+            verifyCaller(callingPkg);
             for (String perm : autoGrantPermissions) {
                 if (mContext.checkPermission(perm, pid, uid) == PERMISSION_GRANTED) {
                     int providerUser = ContentProvider.getUserIdFromUri(uri, userId);
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 48d464c..26b9adc 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -4352,7 +4352,8 @@
             }
             RkpErrorStats atom = atomWrapper.payload.getRkpErrorStats();
             pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                    FrameworkStatsLog.RKP_ERROR_STATS, atom.rkpError, atomWrapper.count));
+                    FrameworkStatsLog.RKP_ERROR_STATS, atom.rkpError, atomWrapper.count,
+                    atom.security_level));
         }
         return StatsManager.PULL_SUCCESS;
     }
diff --git a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
index 7649958..9d26351 100644
--- a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
@@ -22,6 +22,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.os.Build;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -166,6 +167,11 @@
         mWakeLock.release();
     }
 
+    @Override
+    public boolean deviceHasY2038Issue() {
+        return Build.SUPPORTED_32_BIT_ABIS.length > 0;
+    }
+
     private void checkWakeLockHeld() {
         if (!mWakeLock.isHeld()) {
             Slog.wtf(LOG_TAG, "WakeLock " + mWakeLock + " not held");
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
index 721986b..cc5e6fe 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -17,14 +17,26 @@
 
 import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
 import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SERVICE_NAME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_EXTERNAL_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_GNSS_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_MANUAL_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_NETWORK_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SUGGEST_TELEPHONY_TIME;
 import static android.provider.DeviceConfig.NAMESPACE_SYSTEM_TIME;
 
 import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE;
 import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE;
 
+import android.app.time.ExternalTimeSuggestion;
+import android.app.timedetector.GnssTimeSuggestion;
+import android.app.timedetector.ManualTimeSuggestion;
+import android.app.timedetector.NetworkTimeSuggestion;
+import android.app.timedetector.TelephonyTimeSuggestion;
 import android.os.ShellCommand;
 
 import java.io.PrintWriter;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 /** Implements the shell command interface for {@link TimeDetectorService}. */
 class TimeDetectorShellCommand extends ShellCommand {
@@ -44,6 +56,16 @@
         switch (cmd) {
             case SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED:
                 return runIsAutoDetectionEnabled();
+            case SHELL_COMMAND_SUGGEST_MANUAL_TIME:
+                return runSuggestManualTime();
+            case SHELL_COMMAND_SUGGEST_TELEPHONY_TIME:
+                return runSuggestTelephonyTime();
+            case SHELL_COMMAND_SUGGEST_NETWORK_TIME:
+                return runSuggestNetworkTime();
+            case SHELL_COMMAND_SUGGEST_GNSS_TIME:
+                return runSuggestGnssTime();
+            case SHELL_COMMAND_SUGGEST_EXTERNAL_TIME:
+                return runSuggestExternalTime();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -59,6 +81,53 @@
         return 0;
     }
 
+    private int runSuggestManualTime() {
+        return runSuggestTime(
+                () -> ManualTimeSuggestion.parseCommandLineArg(this),
+                mInterface::suggestManualTime);
+    }
+
+    private int runSuggestTelephonyTime() {
+        return runSuggestTime(
+                () -> TelephonyTimeSuggestion.parseCommandLineArg(this),
+                mInterface::suggestTelephonyTime);
+    }
+
+    private int runSuggestNetworkTime() {
+        return runSuggestTime(
+                () -> NetworkTimeSuggestion.parseCommandLineArg(this),
+                mInterface::suggestNetworkTime);
+    }
+
+    private int runSuggestGnssTime() {
+        return runSuggestTime(
+                () -> GnssTimeSuggestion.parseCommandLineArg(this),
+                mInterface::suggestGnssTime);
+    }
+
+    private int runSuggestExternalTime() {
+        return runSuggestTime(
+                () -> ExternalTimeSuggestion.parseCommandLineArg(this),
+                mInterface::suggestExternalTime);
+    }
+
+    private <T> int runSuggestTime(Supplier<T> suggestionParser, Consumer<T> invoker) {
+        final PrintWriter pw = getOutPrintWriter();
+        try {
+            T suggestion = suggestionParser.get();
+            if (suggestion == null) {
+                pw.println("Error: suggestion not specified");
+                return 1;
+            }
+            invoker.accept(suggestion);
+            pw.println("Suggestion " + suggestion + " injected.");
+            return 0;
+        } catch (RuntimeException e) {
+            pw.println(e);
+            return 1;
+        }
+    }
+
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
@@ -68,6 +137,22 @@
         pw.printf("  %s\n", SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED);
         pw.printf("    Prints true/false according to the automatic time detection setting.\n");
         pw.println();
+        pw.printf("  %s <manual suggestion opts>\n", SHELL_COMMAND_SUGGEST_MANUAL_TIME);
+        pw.printf("  %s <telephony suggestion opts>\n", SHELL_COMMAND_SUGGEST_TELEPHONY_TIME);
+        pw.printf("  %s <network suggestion opts>\n", SHELL_COMMAND_SUGGEST_NETWORK_TIME);
+        pw.printf("  %s <gnss suggestion opts>\n", SHELL_COMMAND_SUGGEST_GNSS_TIME);
+        pw.printf("  %s <external suggestion opts>\n", SHELL_COMMAND_SUGGEST_EXTERNAL_TIME);
+        pw.println();
+        ManualTimeSuggestion.printCommandLineOpts(pw);
+        pw.println();
+        TelephonyTimeSuggestion.printCommandLineOpts(pw);
+        pw.println();
+        NetworkTimeSuggestion.printCommandLineOpts(pw);
+        pw.println();
+        GnssTimeSuggestion.printCommandLineOpts(pw);
+        pw.println();
+        ExternalTimeSuggestion.printCommandLineOpts(pw);
+        pw.println();
         pw.printf("This service is also affected by the following device_config flags in the"
                 + " %s namespace:\n", NAMESPACE_SYSTEM_TIME);
         pw.printf("  %s\n", KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index ae4d46c..33ab104 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -85,6 +85,9 @@
      */
     private static final int KEEP_SUGGESTION_HISTORY_SIZE = 10;
 
+    /** The value in Unix epoch milliseconds of the Y2038 issue. */
+    private static final long Y2038_LIMIT_IN_MILLIS = 1000L * Integer.MAX_VALUE;
+
     /**
      * A log that records the decisions / decision metadata that affected the device's system clock
      * time. This is logged in bug reports to assist with debugging issues with detection.
@@ -185,6 +188,12 @@
 
         /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */
         void releaseWakeLock();
+
+        /**
+         * Returns {@code true} if the device may be at risk of time_t overflow (because bionic
+         * defines time_t as a 32-bit signed integer for 32-bit processes).
+         */
+        boolean deviceHasY2038Issue();
     }
 
     static TimeDetectorStrategy create(
@@ -333,6 +342,7 @@
                         .mapToObj(TimeDetectorStrategy::originToString)
                         .collect(joining(",", "[", "]"));
         ipw.println("mEnvironment.autoOriginPriorities()=" + priorities);
+        ipw.println("mEnvironment.deviceHasY2038Issue()=" + mEnvironment.deviceHasY2038Issue());
 
         ipw.println("Time change log:");
         ipw.increaseIndent(); // level 2
@@ -413,6 +423,16 @@
                     + ", suggestion=" + suggestion);
             return false;
         }
+
+        if (newUnixEpochTime.getValue() > Y2038_LIMIT_IN_MILLIS
+                && mEnvironment.deviceHasY2038Issue()) {
+            // This check won't prevent a device's system clock exceeding Integer.MAX_VALUE Unix
+            // seconds through the normal passage of time, but it will stop it jumping above 2038
+            // because of a "bad" suggestion. b/204193177
+            Slog.w(LOG_TAG, "Suggested value is above max time supported by this device."
+                    + " suggestion=" + suggestion);
+            return false;
+        }
         return true;
     }
 
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index 89470ec..5c305c6 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -29,6 +29,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.vcn.VcnManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
@@ -47,6 +48,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.vcn.util.PersistableBundleUtils;
+import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -95,6 +98,10 @@
 
     // TODO (Android T+): Add ability to handle multiple subIds per slot.
     @NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
+
+    @NonNull
+    private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap = new HashMap<>();
+
     @NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
 
     @NonNull
@@ -250,7 +257,10 @@
 
         final TelephonySubscriptionSnapshot newSnapshot =
                 new TelephonySubscriptionSnapshot(
-                        mDeps.getActiveDataSubscriptionId(), newSubIdToInfoMap, privilegedPackages);
+                        mDeps.getActiveDataSubscriptionId(),
+                        newSubIdToInfoMap,
+                        mSubIdToCarrierConfigMap,
+                        privilegedPackages);
 
         // If snapshot was meaningfully updated, fire the callback
         if (!newSnapshot.equals(mCurrentSnapshot)) {
@@ -311,47 +321,77 @@
         }
 
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
-            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
-            if (mDeps.isConfigForIdentifiedCarrier(carrierConfigs)) {
+            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+            if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
                 mReadySubIdsBySlotId.put(slotId, subId);
+
+                final PersistableBundle minimized =
+                        PersistableBundleUtils.minimizeBundle(
+                                carrierConfig, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
+                if (minimized != null) {
+                    mSubIdToCarrierConfigMap.put(subId, new PersistableBundleWrapper(minimized));
+                }
                 handleSubscriptionsChanged();
             }
         } else {
-            mReadySubIdsBySlotId.remove(slotId);
+            final Integer oldSubid = mReadySubIdsBySlotId.remove(slotId);
+            if (oldSubid != null) {
+                mSubIdToCarrierConfigMap.remove(oldSubid);
+            }
             handleSubscriptionsChanged();
         }
     }
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     void setReadySubIdsBySlotId(Map<Integer, Integer> readySubIdsBySlotId) {
+        mReadySubIdsBySlotId.clear();
         mReadySubIdsBySlotId.putAll(readySubIdsBySlotId);
     }
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
+    void setSubIdToCarrierConfigMap(
+            Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap) {
+        mSubIdToCarrierConfigMap.clear();
+        mSubIdToCarrierConfigMap.putAll(subIdToCarrierConfigMap);
+    }
+
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
     Map<Integer, Integer> getReadySubIdsBySlotId() {
         return Collections.unmodifiableMap(mReadySubIdsBySlotId);
     }
 
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    Map<Integer, PersistableBundleWrapper> getSubIdToCarrierConfigMap() {
+        return Collections.unmodifiableMap(mSubIdToCarrierConfigMap);
+    }
+
     /** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
     public static class TelephonySubscriptionSnapshot {
         private final int mActiveDataSubId;
         private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
+        private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap;
         private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;
 
         public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
                 new TelephonySubscriptionSnapshot(
-                        INVALID_SUBSCRIPTION_ID, Collections.emptyMap(), Collections.emptyMap());
+                        INVALID_SUBSCRIPTION_ID,
+                        Collections.emptyMap(),
+                        Collections.emptyMap(),
+                        Collections.emptyMap());
 
         @VisibleForTesting(visibility = Visibility.PRIVATE)
         TelephonySubscriptionSnapshot(
                 int activeDataSubId,
                 @NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
+                @NonNull Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap,
                 @NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
             mActiveDataSubId = activeDataSubId;
             Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
             Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
+            Objects.requireNonNull(subIdToCarrierConfigMap, "subIdToCarrierConfigMap was null");
 
             mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
+            mSubIdToCarrierConfigMap = Collections.unmodifiableMap(subIdToCarrierConfigMap);
 
             final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
             for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
@@ -423,9 +463,40 @@
                     : false;
         }
 
+        /**
+         * Retrieves a carrier config for a subscription in the provided group.
+         *
+         * <p>This method will prioritize non-opportunistic subscriptions, but will use the a
+         * carrier config for an opportunistic subscription if no other subscriptions are found.
+         */
+        @Nullable
+        public PersistableBundleWrapper getCarrierConfigForSubGrp(@NonNull ParcelUuid subGrp) {
+            PersistableBundleWrapper result = null;
+
+            for (int subId : getAllSubIdsInGroup(subGrp)) {
+                final PersistableBundleWrapper config = mSubIdToCarrierConfigMap.get(subId);
+                if (config != null) {
+                    result = config;
+
+                    // Attempt to use (any) non-opportunistic subscription. If this subscription is
+                    // opportunistic, continue and try to find a non-opportunistic subscription,
+                    // using the opportunistic ones as a last resort.
+                    if (!isOpportunistic(subId)) {
+                        return config;
+                    }
+                }
+            }
+
+            return result;
+        }
+
         @Override
         public int hashCode() {
-            return Objects.hash(mActiveDataSubId, mSubIdToInfoMap, mPrivilegedPackages);
+            return Objects.hash(
+                    mActiveDataSubId,
+                    mSubIdToInfoMap,
+                    mSubIdToCarrierConfigMap,
+                    mPrivilegedPackages);
         }
 
         @Override
@@ -438,6 +509,7 @@
 
             return mActiveDataSubId == other.mActiveDataSubId
                     && mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
+                    && mSubIdToCarrierConfigMap.equals(other.mSubIdToCarrierConfigMap)
                     && mPrivilegedPackages.equals(other.mPrivilegedPackages);
         }
 
@@ -448,6 +520,7 @@
 
             pw.println("mActiveDataSubId: " + mActiveDataSubId);
             pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
+            pw.println("mSubIdToCarrierConfigMap: " + mSubIdToCarrierConfigMap);
             pw.println("mPrivilegedPackages: " + mPrivilegedPackages);
 
             pw.decreaseIndent();
@@ -458,6 +531,7 @@
             return "TelephonySubscriptionSnapshot{ "
                     + "mActiveDataSubId=" + mActiveDataSubId
                     + ", mSubIdToInfoMap=" + mSubIdToInfoMap
+                    + ", mSubIdToCarrierConfigMap=" + mSubIdToCarrierConfigMap
                     + ", mPrivilegedPackages=" + mPrivilegedPackages
                     + " }";
         }
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index c96c1ee..2f84fdd 100644
--- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -24,6 +24,7 @@
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
 
 import static com.android.server.VcnManagementService.LOCAL_LOG;
+import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -34,7 +35,6 @@
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
 import android.os.ParcelUuid;
-import android.os.PersistableBundle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Slog;
@@ -81,7 +81,7 @@
             ParcelUuid subscriptionGroup,
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         // mRouteSelectionNetworkRequest requires a network be both VALIDATED and NOT_SUSPENDED
 
         if (networkRecord.isBlocked) {
@@ -119,7 +119,7 @@
             ParcelUuid subscriptionGroup,
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         final NetworkCapabilities caps = networkRecord.networkCapabilities;
         final boolean isSelectedUnderlyingNetwork =
                 currentlySelected != null
@@ -181,7 +181,7 @@
             VcnWifiUnderlyingNetworkTemplate networkPriority,
             UnderlyingNetworkRecord networkRecord,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         final NetworkCapabilities caps = networkRecord.networkCapabilities;
 
         if (!caps.hasTransport(TRANSPORT_WIFI)) {
@@ -204,7 +204,7 @@
     private static boolean isWifiRssiAcceptable(
             UnderlyingNetworkRecord networkRecord,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         final NetworkCapabilities caps = networkRecord.networkCapabilities;
         final boolean isSelectedNetwork =
                 currentlySelected != null
@@ -314,7 +314,7 @@
         return false;
     }
 
-    static int getWifiEntryRssiThreshold(@Nullable PersistableBundle carrierConfig) {
+    static int getWifiEntryRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
         if (carrierConfig != null) {
             return carrierConfig.getInt(
                     VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
@@ -323,7 +323,7 @@
         return WIFI_ENTRY_RSSI_THRESHOLD_DEFAULT;
     }
 
-    static int getWifiExitRssiThreshold(@Nullable PersistableBundle carrierConfig) {
+    static int getWifiExitRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
         if (carrierConfig != null) {
             return carrierConfig.getInt(
                     VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
index a3babf7..d474c5d 100644
--- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
+++ b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
@@ -21,7 +21,7 @@
 import static com.android.server.VcnManagementService.LOCAL_LOG;
 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiEntryRssiThreshold;
 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiExitRssiThreshold;
-import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.isOpportunistic;
+import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,8 +37,6 @@
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
@@ -51,7 +49,6 @@
 import com.android.server.vcn.util.LogUtils;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -87,7 +84,7 @@
     @Nullable private UnderlyingNetworkListener mRouteSelectionCallback;
 
     @NonNull private TelephonySubscriptionSnapshot mLastSnapshot;
-    @Nullable private PersistableBundle mCarrierConfig;
+    @Nullable private PersistableBundleWrapper mCarrierConfig;
     private boolean mIsQuitting = false;
 
     @Nullable private UnderlyingNetworkRecord mCurrentRecord;
@@ -124,25 +121,7 @@
                 .getSystemService(TelephonyManager.class)
                 .registerTelephonyCallback(new HandlerExecutor(mHandler), mActiveDataSubIdListener);
 
-        // TODO: Listen for changes in carrier config that affect this.
-        for (int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) {
-            PersistableBundle config =
-                    mVcnContext
-                            .getContext()
-                            .getSystemService(CarrierConfigManager.class)
-                            .getConfigForSubId(subId);
-
-            if (config != null) {
-                mCarrierConfig = config;
-
-                // Attempt to use (any) non-opportunistic subscription. If this subscription is
-                // opportunistic, continue and try to find a non-opportunistic subscription, using
-                // the opportunistic ones as a last resort.
-                if (!isOpportunistic(mLastSnapshot, Collections.singleton(subId))) {
-                    break;
-                }
-            }
-        }
+        mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);
 
         registerOrUpdateNetworkRequests();
     }
@@ -334,6 +313,9 @@
         final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
         mLastSnapshot = newSnapshot;
 
+        // Update carrier config
+        mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);
+
         // Only trigger re-registration if subIds in this group have changed
         if (oldSnapshot
                 .getAllSubIdsInGroup(mSubscriptionGroup)
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
index 06f9280..319680e 100644
--- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
+++ b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
@@ -16,6 +16,8 @@
 
 package com.android.server.vcn.routeselection;
 
+import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.net.LinkProperties;
@@ -23,7 +25,6 @@
 import android.net.NetworkCapabilities;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.os.ParcelUuid;
-import android.os.PersistableBundle;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -68,7 +69,7 @@
             ParcelUuid subscriptionGroup,
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         // Never changes after the underlying network record is created.
         if (mPriorityClass == PRIORITY_CLASS_INVALID) {
             mPriorityClass =
@@ -113,7 +114,7 @@
             ParcelUuid subscriptionGroup,
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         return (left, right) -> {
             final int leftIndex =
                     left.getOrCalculatePriorityClass(
@@ -167,7 +168,7 @@
             ParcelUuid subscriptionGroup,
             TelephonySubscriptionSnapshot snapshot,
             UnderlyingNetworkRecord currentlySelected,
-            PersistableBundle carrierConfig) {
+            PersistableBundleWrapper carrierConfig) {
         pw.println("UnderlyingNetworkRecord:");
         pw.increaseIndent();
 
diff --git a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
index 1c675c2..999d406 100644
--- a/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
+++ b/services/core/java/com/android/server/vcn/util/PersistableBundleUtils.java
@@ -23,16 +23,20 @@
 
 import com.android.internal.util.HexDump;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.TreeSet;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -294,6 +298,30 @@
     }
 
     /**
+     * Converts a PersistableBundle into a disk-stable byte array format
+     *
+     * @param bundle the PersistableBundle to be converted to a disk-stable format
+     * @return the byte array representation of the PersistableBundle
+     */
+    @Nullable
+    public static byte[] toDiskStableBytes(@NonNull PersistableBundle bundle) throws IOException {
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        bundle.writeToStream(outputStream);
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * Converts from a disk-stable byte array format to a PersistableBundle
+     *
+     * @param bytes the disk-stable byte array
+     * @return the PersistableBundle parsed from this byte array.
+     */
+    public static PersistableBundle fromDiskStableBytes(@NonNull byte[] bytes) throws IOException {
+        final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+        return PersistableBundle.readFromStream(inputStream);
+    }
+
+    /**
      * Ensures safe reading and writing of {@link PersistableBundle}s to and from disk.
      *
      * <p>This class will enforce exclusion between reads and writes using the standard semantics of
@@ -354,4 +382,182 @@
             }
         }
     }
+
+    /**
+     * Returns a copy of the persistable bundle with only the specified keys
+     *
+     * <p>This allows for holding minimized copies for memory-saving purposes.
+     */
+    @NonNull
+    public static PersistableBundle minimizeBundle(
+            @NonNull PersistableBundle bundle, String... keys) {
+        final PersistableBundle minimized = new PersistableBundle();
+
+        if (bundle == null) {
+            return minimized;
+        }
+
+        for (String key : keys) {
+            if (bundle.containsKey(key)) {
+                final Object value = bundle.get(key);
+                if (value == null) {
+                    continue;
+                }
+
+                if (value instanceof Boolean) {
+                    minimized.putBoolean(key, (Boolean) value);
+                } else if (value instanceof boolean[]) {
+                    minimized.putBooleanArray(key, (boolean[]) value);
+                } else if (value instanceof Double) {
+                    minimized.putDouble(key, (Double) value);
+                } else if (value instanceof double[]) {
+                    minimized.putDoubleArray(key, (double[]) value);
+                } else if (value instanceof Integer) {
+                    minimized.putInt(key, (Integer) value);
+                } else if (value instanceof int[]) {
+                    minimized.putIntArray(key, (int[]) value);
+                } else if (value instanceof Long) {
+                    minimized.putLong(key, (Long) value);
+                } else if (value instanceof long[]) {
+                    minimized.putLongArray(key, (long[]) value);
+                } else if (value instanceof String) {
+                    minimized.putString(key, (String) value);
+                } else if (value instanceof String[]) {
+                    minimized.putStringArray(key, (String[]) value);
+                } else if (value instanceof PersistableBundle) {
+                    minimized.putPersistableBundle(key, (PersistableBundle) value);
+                } else {
+                    continue;
+                }
+            }
+        }
+
+        return minimized;
+    }
+
+    /** Builds a stable hashcode */
+    public static int getHashCode(@Nullable PersistableBundle bundle) {
+        if (bundle == null) {
+            return -1;
+        }
+
+        int iterativeHashcode = 0;
+        TreeSet<String> treeSet = new TreeSet<>(bundle.keySet());
+        for (String key : treeSet) {
+            Object val = bundle.get(key);
+            if (val instanceof PersistableBundle) {
+                iterativeHashcode =
+                        Objects.hash(iterativeHashcode, key, getHashCode((PersistableBundle) val));
+            } else {
+                iterativeHashcode = Objects.hash(iterativeHashcode, key, val);
+            }
+        }
+
+        return iterativeHashcode;
+    }
+
+    /** Checks for persistable bundle equality */
+    public static boolean isEqual(
+            @Nullable PersistableBundle left, @Nullable PersistableBundle right) {
+        // Check for pointer equality & null equality
+        if (Objects.equals(left, right)) {
+            return true;
+        }
+
+        // If only one of the two is null, but not the other, not equal by definition.
+        if (Objects.isNull(left) != Objects.isNull(right)) {
+            return false;
+        }
+
+        if (!left.keySet().equals(right.keySet())) {
+            return false;
+        }
+
+        for (String key : left.keySet()) {
+            Object leftVal = left.get(key);
+            Object rightVal = right.get(key);
+
+            // Check for equality
+            if (Objects.equals(leftVal, rightVal)) {
+                continue;
+            } else if (Objects.isNull(leftVal) != Objects.isNull(rightVal)) {
+                // If only one of the two is null, but not the other, not equal by definition.
+                return false;
+            } else if (!Objects.equals(leftVal.getClass(), rightVal.getClass())) {
+                // If classes are different, not equal by definition.
+                return false;
+            }
+            if (leftVal instanceof PersistableBundle) {
+                if (!isEqual((PersistableBundle) leftVal, (PersistableBundle) rightVal)) {
+                    return false;
+                }
+            } else if (leftVal.getClass().isArray()) {
+                if (leftVal instanceof boolean[]) {
+                    if (!Arrays.equals((boolean[]) leftVal, (boolean[]) rightVal)) {
+                        return false;
+                    }
+                } else if (leftVal instanceof double[]) {
+                    if (!Arrays.equals((double[]) leftVal, (double[]) rightVal)) {
+                        return false;
+                    }
+                } else if (leftVal instanceof int[]) {
+                    if (!Arrays.equals((int[]) leftVal, (int[]) rightVal)) {
+                        return false;
+                    }
+                } else if (leftVal instanceof long[]) {
+                    if (!Arrays.equals((long[]) leftVal, (long[]) rightVal)) {
+                        return false;
+                    }
+                } else if (!Arrays.equals((Object[]) leftVal, (Object[]) rightVal)) {
+                    return false;
+                }
+            } else {
+                if (!Objects.equals(leftVal, rightVal)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Wrapper class around PersistableBundles to allow equality comparisons
+     *
+     * <p>This class exposes the minimal getters to retrieve values.
+     */
+    public static class PersistableBundleWrapper {
+        @NonNull private final PersistableBundle mBundle;
+
+        public PersistableBundleWrapper(@NonNull PersistableBundle bundle) {
+            mBundle = Objects.requireNonNull(bundle, "Bundle was null");
+        }
+
+        /**
+         * Retrieves the integer associated with the provided key.
+         *
+         * @param key the string key to query
+         * @param defaultValue the value to return if key does not exist
+         * @return the int value, or the default
+         */
+        public int getInt(String key, int defaultValue) {
+            return mBundle.getInt(key, defaultValue);
+        }
+
+        @Override
+        public int hashCode() {
+            return getHashCode(mBundle);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof PersistableBundleWrapper)) {
+                return false;
+            }
+
+            final PersistableBundleWrapper other = (PersistableBundleWrapper) obj;
+
+            return isEqual(mBundle, other.mBundle);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index badb1f5..4708d00 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -97,7 +97,7 @@
         // activities are actually behind other fullscreen activities, but still required
         // to be visible (such as performing Recents animation).
         final boolean resumeTopActivity = mTop != null && !mTop.mLaunchTaskBehind
-                && mTaskFragment.isTopActivityFocusable()
+                && mTaskFragment.canBeResumed(starting)
                 && (starting == null || !starting.isDescendantOf(mTaskFragment));
 
         ArrayList<TaskFragment> adjacentTaskFragments = null;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fbc8f73..628e124 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1979,7 +1979,8 @@
 
         try {
             if (mTaskSupervisor.realStartActivityLocked(r, app,
-                    top == r && r.isFocusable() /*andResume*/, true /*checkConfig*/)) {
+                    top == r && r.getTask().canBeResumed(r) /*andResume*/,
+                    true /*checkConfig*/)) {
                 mTmpBoolean = true;
             }
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 40c7b3b..8839fba 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3297,9 +3297,6 @@
         if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
             throw new SecurityException("Requires CONTROL_KEYGUARD permission");
         }
-        if (mAtmInternal.isDreaming()) {
-            mAtmService.mTaskSupervisor.wakeUp("dismissKeyguard");
-        }
         synchronized (mGlobalLock) {
             mPolicy.dismissKeyguardLw(callback, message);
         }
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index 51bc99a..8567110 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -2,7 +2,7 @@
 per-file com_android_server_lights_LightsService.cpp = michaelwr@google.com, santoscordon@google.com
 
 # Input
-per-file com_android_server_input_InputManagerService.cpp = michaelwr@google.com, svv@google.com
+per-file com_android_server_input_* = file:/INPUT_OWNERS
 
 # Power
 per-file com_android_server_HardwarePropertiesManagerService.cpp = michaelwr@google.com, santoscordon@google.com
@@ -15,7 +15,6 @@
 per-file com_android_server_Usb* = file:/services/usb/OWNERS
 per-file com_android_server_Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNERS
 per-file com_android_server_hdmi_* = file:/core/java/android/hardware/hdmi/OWNERS
-per-file com_android_server_input_* = file:/core/java/android/hardware/input/OWNERS
 per-file com_android_server_lights_* = file:/services/core/java/com/android/server/lights/OWNERS
 per-file com_android_server_location_* = file:/location/java/android/location/OWNERS
 per-file com_android_server_locksettings_* = file:/services/core/java/com/android/server/locksettings/OWNERS
@@ -23,8 +22,7 @@
 per-file com_android_server_pm_* = file:/services/core/java/com/android/server/pm/OWNERS
 per-file com_android_server_power_* = file:/services/core/java/com/android/server/power/OWNERS
 per-file com_android_server_powerstats_* = file:/services/core/java/com/android/server/powerstats/OWNERS
-per-file com_android_server_se_* = file:/core/java/android/se/OWNERS
 per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
 per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
 per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
-per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
\ No newline at end of file
+per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8e4afe6..dc729f2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1382,8 +1382,9 @@
                     Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
                     TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
                     traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD);
-                    if (!Process.ZYGOTE_PROCESS.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) {
-                        Slog.e(TAG, "Unable to preload default resources");
+                    String[] abis32 = Build.SUPPORTED_32_BIT_ABIS;
+                    if (abis32.length > 0 && !Process.ZYGOTE_PROCESS.preloadDefault(abis32[0])) {
+                        Slog.e(TAG, "Unable to preload default resources for secondary");
                     }
                     traceLog.traceEnd();
                 } catch (Exception ex) {
diff --git a/services/proguard.flags b/services/proguard.flags
index 425da6c..bad02b4 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -33,6 +33,11 @@
   public <init>(...);
 }
 
+# Accessed from com.android.compos APEX
+-keep,allowoptimization,allowaccessmodification class com.android.internal.art.ArtStatsLog {
+   public static void write(...);
+}
+
 # Binder interfaces
 -keep,allowoptimization,allowaccessmodification class * extends android.os.IInterface
 -keep,allowoptimization,allowaccessmodification class * extends android.os.IHwInterface
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
index 7e4f0e7..2617f4d 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
@@ -38,5 +38,4 @@
         "androidx.test.rules",
         "truth-prebuilt",
     ],
-    platform_apis: true,
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index bdf94f3..3151552 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -1037,6 +1037,12 @@
         }
 
         @Override
+        public AtomicFile getLegacyFile(String filename) {
+            // Don't have the test write / read from anywhere.
+            return null;
+        }
+
+        @Override
         public long currentTimeMillis() {
             return mCurrentTimeMillis;
         }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index a227cd3..035249e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -70,6 +70,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -516,6 +517,7 @@
         }
     }
 
+    @Ignore("Causing breakages so ignoring to resolve, b/231667368")
     @Test
     public void initRecoveryService_alwaysUpdatesCertsWhenTestRootCertIsUsed() throws Exception {
         int uid = Binder.getCallingUid();
@@ -539,6 +541,7 @@
                 testRootCertAlias)).isEqualTo(TestData.getInsecureCertPathForEndpoint2());
     }
 
+    @Ignore("Causing breakages so ignoring to resolve, b/231667368")
     @Test
     public void initRecoveryService_updatesCertsIndependentlyForDifferentRoots() throws Exception {
         int uid = Binder.getCallingUid();
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
index c489cf0..de83e51 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
@@ -17,6 +17,8 @@
 package com.android.server.pm;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.verify;
@@ -129,22 +131,16 @@
     }
 
     @Test
-    public void testDestroyUserData() throws Exception {
-        // Add file in CE
+    public void testDestroyUserData_De_DoesNotDestroyCe() throws Exception {
+        // Add file in CE storage
         File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
         systemCeDir.mkdirs();
         File ceFile = new File(systemCeDir, "file");
         writeFile(ceFile, "-----" );
-        testDestroyUserData_De();
-        // CE directory should be preserved
+        // Destroy DE storage, then verify that CE storage wasn't destroyed too.
+        mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_DE);
         assertEquals(Collections.singletonList(ceFile), Arrays.asList(FileUtils.listFilesOrEmpty(
                 systemCeDir)));
-
-        testDestroyUserData_Ce();
-
-        // Verify that testDir is empty
-        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
-                mUserDataPreparer.testDir)));
     }
 
     @Test
@@ -163,7 +159,13 @@
         verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
                         eq(StorageManager.FLAG_STORAGE_DE));
 
-        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(systemDir)));
+        // systemDir (normal path: /data/system/users/$userId) should have been deleted.
+        assertFalse(systemDir.exists());
+        // systemDeDir (normal path: /data/system_de/$userId) should still exist but be empty, since
+        // UserDataPreparer itself is responsible for deleting the contents of this directory, but
+        // it delegates to StorageManager.destroyUserStorage() for deleting the directory itself.
+        // We've mocked out StorageManager, so StorageManager.destroyUserStorage() will be a no-op.
+        assertTrue(systemDeDir.exists());
         assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
                 systemDeDir)));
     }
@@ -181,6 +183,11 @@
         verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
                 eq(StorageManager.FLAG_STORAGE_CE));
 
+        // systemCeDir (normal path: /data/system_ce/$userId) should still exist but be empty, since
+        // UserDataPreparer itself is responsible for deleting the contents of this directory, but
+        // it delegates to StorageManager.destroyUserStorage() for deleting the directory itself.
+        // We've mocked out StorageManager, so StorageManager.destroyUserStorage() will be a no-op.
+        assertTrue(systemCeDir.exists());
         assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
                 systemCeDir)));
     }
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 2d9903f..2248ddb 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -1131,6 +1131,49 @@
                 .verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
     }
 
+    @Test
+    public void manualY2038SuggestionsAreRejectedOnAffectedDevices() {
+        mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+                .pokeAutoTimeDetectionEnabled(false)
+                .pokeAutoOriginPriorities(ORIGIN_TELEPHONY)
+                .pokeDeviceHasY2038Issues(true);
+
+        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
+        ManualTimeSuggestion timeSuggestion = mScript.generateManualTimeSuggestion(y2038IssueTime);
+        mScript.simulateManualTimeSuggestion(timeSuggestion, false /* expectedResult */)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void telephonyY2038SuggestionsAreRejectedOnAffectedDevices() {
+        mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+                .pokeAutoTimeDetectionEnabled(true)
+                .pokeAutoOriginPriorities(ORIGIN_TELEPHONY)
+                .pokeDeviceHasY2038Issues(true);
+
+        final int slotIndex = 0;
+        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
+        TelephonyTimeSuggestion timeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void telephonyY2038SuggestionsAreNotRejectedOnUnaffectedDevices() {
+        mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
+                .pokeAutoTimeDetectionEnabled(true)
+                .pokeAutoOriginPriorities(ORIGIN_TELEPHONY)
+                .pokeDeviceHasY2038Issues(false);
+
+        final int slotIndex = 0;
+        Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
+        TelephonyTimeSuggestion timeSuggestion =
+                mScript.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
+        mScript.simulateTelephonyTimeSuggestion(timeSuggestion)
+                .verifySystemClockWasSetAndResetCallTracking(y2038IssueTime.toEpochMilli());
+    }
+
     /**
      * A fake implementation of {@link TimeDetectorStrategyImpl.Environment}. Besides tracking
      * changes and behaving like the real thing should, it also asserts preconditions.
@@ -1143,6 +1186,7 @@
         private int mSystemClockUpdateThresholdMillis = 2000;
         private int[] mAutoOriginPriorities = PROVIDERS_PRIORITY;
         private ConfigurationChangeListener mConfigChangeListener;
+        private boolean mDeviceHas2038Issues = false;
 
         // Tracking operations.
         private boolean mSystemClockWasSet;
@@ -1208,6 +1252,15 @@
             mWakeLockAcquired = false;
         }
 
+        public void setDeviceHas2038Issues(boolean hasIssues) {
+            mDeviceHas2038Issues = hasIssues;
+        }
+
+        @Override
+        public boolean deviceHasY2038Issue() {
+            return mDeviceHas2038Issues;
+        }
+
         // Methods below are for managing the fake's behavior.
 
         void pokeSystemClockUpdateThreshold(int thresholdMillis) {
@@ -1304,6 +1357,11 @@
             return this;
         }
 
+        Script pokeDeviceHasY2038Issues(boolean hasIssues) {
+            mFakeEnvironment.setDeviceHas2038Issues(hasIssues);
+            return this;
+        }
+
         long peekElapsedRealtimeMillis() {
             return mFakeEnvironment.peekElapsedRealtimeMillis();
         }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
index 1126e1e..4b6183d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
@@ -15,16 +15,22 @@
  */
 package com.android.server.notification;
 
+import static android.os.UserHandle.USER_ALL;
 import static android.os.UserHandle.USER_CURRENT;
+import static android.os.UserHandle.USER_NULL;
 import static android.os.UserHandle.USER_SYSTEM;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
 
 import android.app.Notification;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -35,6 +41,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
@@ -51,6 +58,8 @@
     private static final int SIZE = 5;
 
     private NotificationManagerService.Archive mArchive;
+    @Mock
+    private UserManager mUm;
 
     @Before
     public void setUp() {
@@ -59,6 +68,9 @@
         mArchive = new NotificationManagerService.Archive(SIZE);
         mArchive.updateHistoryEnabled(USER_SYSTEM, true);
         mArchive.updateHistoryEnabled(USER_CURRENT, true);
+
+        when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(
+                new int[] {USER_CURRENT, USER_SYSTEM});
     }
 
     private StatusBarNotification getNotification(String pkg, int id, UserHandle user) {
@@ -70,7 +82,6 @@
                 pkg, pkg, id, null, 0, 0, n, user, null, System.currentTimeMillis());
     }
 
-
     @Test
     public void testRecordAndRead() {
         List<String> expected = new ArrayList<>();
@@ -81,7 +92,7 @@
             mArchive.record(sbn, REASON_CANCEL);
         }
 
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
@@ -89,6 +100,22 @@
     }
 
     @Test
+    public void testCrossUser() {
+        mArchive.record(getNotification("pkg", 1, UserHandle.of(USER_SYSTEM)), REASON_CANCEL);
+        mArchive.record(getNotification("pkg", 2, UserHandle.of(USER_CURRENT)), REASON_CANCEL);
+        mArchive.record(getNotification("pkg", 3, UserHandle.of(USER_ALL)), REASON_CANCEL);
+        mArchive.record(getNotification("pkg", 4, UserHandle.of(USER_NULL)), REASON_CANCEL);
+
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
+        assertThat(actual).hasSize(3);
+        for (StatusBarNotification sbn : actual) {
+            if (sbn.getUserId() == USER_NULL) {
+                fail("leaked notification from wrong user");
+            }
+        }
+    }
+
+    @Test
     public void testRecordAndRead_overLimit() {
         List<String> expected = new ArrayList<>();
         for (int i = 0; i < (SIZE * 2); i++) {
@@ -99,7 +126,8 @@
             }
         }
 
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray((SIZE * 2), true));
+        List<StatusBarNotification> actual = Arrays.asList(
+                mArchive.getArray(mUm, (SIZE * 2), true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
@@ -119,7 +147,7 @@
             }
         }
 
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
@@ -140,7 +168,7 @@
         }
         mArchive.updateHistoryEnabled(USER_CURRENT, false);
 
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
@@ -165,7 +193,7 @@
         }
         mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test0");
         mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test" + (SIZE - 2));
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
@@ -215,7 +243,7 @@
             fail("Concurrent modification exception");
         }
 
-        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+        List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
         assertThat(actual).hasSize(expected.size());
         for (StatusBarNotification sbn : actual) {
             assertThat(expected).contains(sbn.getKey());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e98d077..339a0a8 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -475,6 +475,7 @@
         when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
         when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
         mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
+        when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
 
         // write to a test file; the system file isn't readable from tests
         mFile = new File(mContext.getCacheDir(), "test.xml");
@@ -6970,8 +6971,9 @@
         waitForIdle();
 
         // A notification exists for the given record
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
-        assertEquals(1, notifsBefore.length);
+        List<StatusBarNotification> notifsBefore =
+                mBinderService.getAppActiveNotifications(PKG, nr.getSbn().getUserId()).getList();
+        assertEquals(1, notifsBefore.size());
 
         reset(mPackageManager);
 
@@ -8289,4 +8291,33 @@
         assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001)));
         assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("test", 1002)));
     }
+
+    @Test
+    public void testGetActiveNotification_filtersUsers() throws Exception {
+        when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0, 10});
+
+        NotificationRecord nr0 =
+                generateNotificationRecord(mTestNotificationChannel, 0);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+                nr0.getSbn().getId(), nr0.getSbn().getNotification(), nr0.getSbn().getUserId());
+
+        NotificationRecord nr10 =
+                generateNotificationRecord(mTestNotificationChannel, 10);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag10",
+                nr10.getSbn().getId(), nr10.getSbn().getNotification(), nr10.getSbn().getUserId());
+
+        NotificationRecord nr11 =
+                generateNotificationRecord(mTestNotificationChannel, 11);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag11",
+                nr11.getSbn().getId(), nr11.getSbn().getNotification(), nr11.getSbn().getUserId());
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(2, notifs.length);
+        for (StatusBarNotification sbn : notifs) {
+            if (sbn.getUserId() == 11) {
+                fail("leaked data across users");
+            }
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index a91298f..10011fd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -31,7 +31,6 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -42,7 +41,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -158,16 +156,6 @@
     }
 
     @Test
-    public void testDismissKeyguardCanWakeUp() {
-        doReturn(true).when(mWm).checkCallingPermission(anyString(), anyString());
-        spyOn(mWm.mAtmInternal);
-        doReturn(true).when(mWm.mAtmInternal).isDreaming();
-        doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
-        mWm.dismissKeyguard(null, "test-dismiss-keyguard");
-        verify(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
-    }
-
-    @Test
     public void testMoveWindowTokenToDisplay_NullToken_DoNothing() {
         mWm.moveWindowTokenToDisplay(null, mDisplayContent.getDisplayId());
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index ac1fcce..f5047bf 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -76,7 +76,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -140,13 +139,26 @@
     private static final boolean ENABLE_KERNEL_UPDATES = true;
     private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set");
 
-    private static final File USAGE_STATS_LEGACY_DIR = new File(
-            Environment.getDataSystemDirectory(), "usagestats");
-    // For migration purposes, indicates whether to keep the legacy usage stats directory or not
-    private static final boolean KEEP_LEGACY_DIR = false;
+    // /data/system/usagestats.  Now only used for globalcomponentusage.  Previously per-user stats
+    // were stored here too, but they've been moved to /data/system_ce/$userId/usagestats.
+    private static final File COMMON_USAGE_STATS_DIR =
+            new File(Environment.getDataSystemDirectory(), "usagestats");
+    private static final File LEGACY_USER_USAGE_STATS_DIR = COMMON_USAGE_STATS_DIR;
 
-    private static final File COMMON_USAGE_STATS_DE_DIR =
+    // /data/system_de/usagestats.  When the globalcomponentusage file was added, it was incorrectly
+    // added here instead of in /data/system/usagestats where it should be.  We lazily migrate this
+    // file by reading it from here if needed, and always writing it to the new path.  We don't
+    // delete the old directory, as system_server no longer has permission to do so.
+    //
+    // Note, this migration is *not* related to the migration of the per-user stats from
+    // /data/system/usagestats/$userId to /data/system_ce/$userId/usagestats mentioned above.  Both
+    // of these just happen to involve /data/system/usagestats.  /data/system is the right place for
+    // system data not tied to a user, but the wrong place for per-user data.  So due to two
+    // separate mistakes, we've unfortunately ended up with one case where we need to move files out
+    // of /data/system, and one case where we need to move a different file *into* /data/system.
+    private static final File LEGACY_COMMON_USAGE_STATS_DIR =
             new File(Environment.getDataSystemDeDirectory(), "usagestats");
+
     private static final String GLOBAL_COMPONENT_USAGE_FILE_NAME = "globalcomponentusage";
 
     private static final char TOKEN_DELIMITER = '/';
@@ -630,7 +642,7 @@
                 final int previousVersion = Integer.parseInt(reader.readLine());
                 // UsageStatsDatabase.BACKUP_VERSION was 4 when usage stats were migrated to CE.
                 if (previousVersion >= 4) {
-                    deleteLegacyDir(userId);
+                    deleteLegacyUserDir(userId);
                     return;
                 }
                 // If migration logic needs to be changed in a future version, do it here.
@@ -651,7 +663,7 @@
         }
 
         Slog.i(TAG, "Starting migration to system CE for user " + userId);
-        final File legacyUserDir = new File(USAGE_STATS_LEGACY_DIR, Integer.toString(userId));
+        final File legacyUserDir = new File(LEGACY_USER_USAGE_STATS_DIR, Integer.toString(userId));
         if (legacyUserDir.exists()) {
             copyRecursively(usageStatsDir, legacyUserDir);
         }
@@ -666,8 +678,8 @@
         }
         Slog.i(TAG, "Finished migration to system CE for user " + userId);
 
-        // Migration was successful - delete the legacy directory
-        deleteLegacyDir(userId);
+        // Migration was successful - delete the legacy user directory
+        deleteLegacyUserDir(userId);
     }
 
     private static void copyRecursively(final File parent, File f) {
@@ -698,21 +710,14 @@
         }
     }
 
-    private void deleteLegacyDir(int userId) {
-        final File legacyUserDir = new File(USAGE_STATS_LEGACY_DIR, Integer.toString(userId));
-        if (!KEEP_LEGACY_DIR && legacyUserDir.exists()) {
+    private void deleteLegacyUserDir(int userId) {
+        final File legacyUserDir = new File(LEGACY_USER_USAGE_STATS_DIR, Integer.toString(userId));
+        if (legacyUserDir.exists()) {
             deleteRecursively(legacyUserDir);
             if (legacyUserDir.exists()) {
                 Slog.w(TAG, "Error occurred while attempting to delete legacy usage stats "
                         + "dir for user " + userId);
             }
-            // If all users have been migrated, delete the parent legacy usage stats directory
-            if (USAGE_STATS_LEGACY_DIR.list() != null
-                    && USAGE_STATS_LEGACY_DIR.list().length == 0) {
-                if (!USAGE_STATS_LEGACY_DIR.delete()) {
-                    Slog.w(TAG, "Error occurred while attempting to delete legacy usage stats dir");
-                }
-            }
         }
     }
 
@@ -807,13 +812,16 @@
     }
 
     private void loadGlobalComponentUsageLocked() {
-        final File[] packageUsageFile = COMMON_USAGE_STATS_DE_DIR.listFiles(
-                (dir, name) -> TextUtils.equals(name, GLOBAL_COMPONENT_USAGE_FILE_NAME));
-        if (packageUsageFile == null || packageUsageFile.length == 0) {
-            return;
+        AtomicFile af = new AtomicFile(new File(COMMON_USAGE_STATS_DIR,
+                    GLOBAL_COMPONENT_USAGE_FILE_NAME));
+        if (!af.exists()) {
+            af = new AtomicFile(new File(LEGACY_COMMON_USAGE_STATS_DIR,
+                        GLOBAL_COMPONENT_USAGE_FILE_NAME));
+            if (!af.exists()) {
+                return;
+            }
+            Slog.i(TAG, "Reading " + GLOBAL_COMPONENT_USAGE_FILE_NAME + " file from old location");
         }
-
-        final AtomicFile af = new AtomicFile(packageUsageFile[0]);
         final Map<String, Long> tmpUsage = new ArrayMap<>();
         try {
             try (FileInputStream in = af.openRead()) {
@@ -831,7 +839,7 @@
             }
         } catch (Exception e) {
             // Most likely trying to read a corrupted file - log the failure
-            Slog.e(TAG, "Could not read " + packageUsageFile[0]);
+            Slog.e(TAG, "Could not read " + af.getBaseFile());
         }
     }
 
@@ -840,11 +848,11 @@
             return;
         }
 
-        if (!COMMON_USAGE_STATS_DE_DIR.mkdirs() && !COMMON_USAGE_STATS_DE_DIR.exists()) {
-            throw new IllegalStateException("Common usage stats DE directory does not exist: "
-                    + COMMON_USAGE_STATS_DE_DIR.getAbsolutePath());
+        if (!COMMON_USAGE_STATS_DIR.mkdirs() && !COMMON_USAGE_STATS_DIR.exists()) {
+            throw new IllegalStateException("Common usage stats directory does not exist: "
+                    + COMMON_USAGE_STATS_DIR.getAbsolutePath());
         }
-        final File lastTimePackageFile = new File(COMMON_USAGE_STATS_DE_DIR,
+        final File lastTimePackageFile = new File(COMMON_USAGE_STATS_DIR,
                 GLOBAL_COMPONENT_USAGE_FILE_NAME);
         final AtomicFile af = new AtomicFile(lastTimePackageFile);
         FileOutputStream fos = null;
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index 01feacd..4dc5423 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -29,6 +29,7 @@
         "android.hardware.usb-V1.1-java",
         "android.hardware.usb-V1.2-java",
         "android.hardware.usb-V1.3-java",
+        "android.hardware.usb-V1-java",
         "android.hardware.usb.gadget-V1.0-java",
         "android.hardware.usb.gadget-V1.1-java",
         "android.hardware.usb.gadget-V1.2-java",
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ec28040..d472639 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -16,6 +16,8 @@
 
 package com.android.server.usb;
 
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_PORT_MISMATCH;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
 import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
 import static android.hardware.usb.UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
@@ -25,6 +27,12 @@
 import static android.hardware.usb.UsbPortStatus.MODE_UFP;
 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_POWER_ROLE_SOURCE;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_POWER_ROLE_SINK;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_DATA_ROLE_HOST;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_DATA_ROLE_DEVICE;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_MODE_DFP;
+import static com.android.server.usb.hal.port.UsbPortHal.HAL_MODE_UFP;
 
 import static com.android.internal.usb.DumpUtils.writePort;
 import static com.android.internal.usb.DumpUtils.writePortStatus;
@@ -38,6 +46,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.hardware.usb.IUsbOperationInternal;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
@@ -74,9 +83,13 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.server.FgThread;
+import com.android.server.usb.hal.port.RawPortInfo;
+import com.android.server.usb.hal.port.UsbPortHal;
+import com.android.server.usb.hal.port.UsbPortHalInstance;
 
 import java.util.ArrayList;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 
 /**
  * Allows trusted components to control the properties of physical USB ports
@@ -109,16 +122,9 @@
     // The system context.
     private final Context mContext;
 
-    // Proxy object for the usb hal daemon.
-    @GuardedBy("mLock")
-    private IUsb mProxy = null;
-
     // Callback when the UsbPort status is changed by the kernel.
     // Mostly due a command sent by the remote Usb device.
-    private HALCallback mHALCallback = new HALCallback(null, this);
-
-    // Cookie sent for usb hal death notification.
-    private static final int USB_HAL_DEATH_COOKIE = 1000;
+    //private HALCallback mHALCallback = new HALCallback(null, this);
 
     // Used as the key while sending the bundle to Main thread.
     private static final String PORT_INFO = "port_info";
@@ -156,36 +162,23 @@
      */
     private int mIsPortContaminatedNotificationId;
 
-    private boolean mEnableUsbDataSignaling;
-    protected int mCurrentUsbHalVersion;
+    private UsbPortHal mUsbPortHal;
+
+    private long mTransactionId;
 
     public UsbPortManager(Context context) {
         mContext = context;
-        try {
-            ServiceNotification serviceNotification = new ServiceNotification();
-
-            boolean ret = IServiceManager.getService()
-                    .registerForNotifications("android.hardware.usb@1.0::IUsb",
-                            "", serviceNotification);
-            if (!ret) {
-                logAndPrint(Log.ERROR, null,
-                        "Failed to register service start notification");
-            }
-        } catch (RemoteException e) {
-            logAndPrintException(null,
-                    "Failed to register service start notification", e);
-            return;
-        }
-        connectToProxy(null);
+        mUsbPortHal = UsbPortHalInstance.getInstance(this, null);
+        logAndPrint(Log.DEBUG, null, "getInstance done");
     }
 
     public void systemReady() {
-	mSystemReady = true;
-        if (mProxy != null) {
+        mSystemReady = true;
+        if (mUsbPortHal != null) {
+            mUsbPortHal.systemReady();
             try {
-                mProxy.queryPortStatus();
-                mEnableUsbDataSignaling = true;
-            } catch (RemoteException e) {
+                mUsbPortHal.queryPortStatus(++mTransactionId);
+            } catch (Exception e) {
                 logAndPrintException(null,
                         "ServiceStart: Failed to query port status", e);
             }
@@ -340,13 +333,9 @@
         }
 
         try {
-            // Oneway call into the hal. Use the castFrom method from HIDL.
-            android.hardware.usb.V1_2.IUsb proxy = android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
-            proxy.enableContaminantPresenceDetection(portId, enable);
-        } catch (RemoteException e) {
+            mUsbPortHal.enableContaminantPresenceDetection(portId, enable, ++mTransactionId);
+        } catch (Exception e) {
             logAndPrintException(pw, "Failed to set contaminant detection", e);
-        } catch (ClassCastException e) {
-            logAndPrintException(pw, "Method only applicable to V1.2 or above implementation", e);
         }
     }
 
@@ -355,46 +344,79 @@
      *
      * @param enable enable or disable USB data signaling
      */
-    public boolean enableUsbDataSignal(boolean enable) {
-        try {
-            mEnableUsbDataSignaling = enable;
-            // Call into the hal. Use the castFrom method from HIDL.
-            android.hardware.usb.V1_3.IUsb proxy = android.hardware.usb.V1_3.IUsb.castFrom(mProxy);
-            return proxy.enableUsbDataSignal(enable);
-        } catch (RemoteException e) {
-            logAndPrintException(null, "Failed to set USB data signaling", e);
-            return false;
-        } catch (ClassCastException e) {
-            logAndPrintException(null, "Method only applicable to V1.3 or above implementation", e);
+    public boolean enableUsbData(@NonNull String portId, boolean enable, int transactionId,
+            @NonNull IUsbOperationInternal callback, IndentingPrintWriter pw) {
+        Objects.requireNonNull(callback);
+        Objects.requireNonNull(portId);
+        final PortInfo portInfo = mPorts.get(portId);
+        if (portInfo == null) {
+            logAndPrint(Log.ERROR, pw, "enableUsbData: No such port: " + portId
+                    + " opId:" + transactionId);
+            try {
+                callback.onOperationComplete(USB_OPERATION_ERROR_PORT_MISMATCH);
+            } catch (RemoteException e) {
+                logAndPrintException(pw,
+                        "enableUsbData: Failed to call OperationComplete. opId:"
+                        + transactionId, e);
+            }
             return false;
         }
+
+        try {
+            try {
+                return mUsbPortHal.enableUsbData(portId, enable, transactionId, callback);
+            } catch (Exception e) {
+                logAndPrintException(pw,
+                    "enableUsbData: Failed to invoke enableUsbData. opId:"
+                    + transactionId , e);
+                callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(pw,
+                    "enableUsbData: Failed to call onOperationComplete. opId:"
+                    + transactionId, e);
+        }
+
+        return false;
     }
 
     /**
      * Get USB HAL version
      *
      * @param none
+     * @return {@link UsbManager#USB_HAL_RETRY} returned when hal version
+     *         is yet to be determined.
      */
     public int getUsbHalVersion() {
-        return mCurrentUsbHalVersion;
+        if (mUsbPortHal != null) {
+            try {
+                return mUsbPortHal.getUsbHalVersion();
+            } catch (RemoteException e) {
+                return UsbManager.USB_HAL_RETRY;
+            }
+        }
+        return UsbManager.USB_HAL_RETRY;
     }
 
-    /**
-     * update USB HAL version
-     *
-     * @param none
-     */
-    private void updateUsbHalVersion() {
-        if (android.hardware.usb.V1_3.IUsb.castFrom(mProxy) != null) {
-            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_3;
-        } else if (android.hardware.usb.V1_2.IUsb.castFrom(mProxy) != null) {
-            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_2;
-        } else if (android.hardware.usb.V1_1.IUsb.castFrom(mProxy) != null) {
-            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_1;
-        } else {
-            mCurrentUsbHalVersion = UsbManager.USB_HAL_V1_0;
-        }
-        logAndPrint(Log.INFO, null, "USB HAL version: " + mCurrentUsbHalVersion);
+    private int toHalUsbDataRole(int usbDataRole) {
+        if (usbDataRole == DATA_ROLE_DEVICE)
+            return HAL_DATA_ROLE_DEVICE;
+        else
+            return HAL_DATA_ROLE_HOST;
+    }
+
+    private int toHalUsbPowerRole(int usbPowerRole) {
+        if (usbPowerRole == POWER_ROLE_SINK)
+            return HAL_POWER_ROLE_SINK;
+        else
+            return HAL_POWER_ROLE_SOURCE;
+    }
+
+    private int toHalUsbMode(int usbMode) {
+        if (usbMode == MODE_UFP)
+            return HAL_MODE_UFP;
+        else
+            return HAL_MODE_DFP;
     }
 
     public void setPortRoles(String portId, int newPowerRole, int newDataRole,
@@ -473,7 +495,7 @@
                 sim.currentPowerRole = newPowerRole;
                 sim.currentDataRole = newDataRole;
                 updatePortsLocked(pw, null);
-            } else if (mProxy != null) {
+            } else if (mUsbPortHal != null) {
                 if (currentMode != newMode) {
                     // Changing the mode will have the side-effect of also changing
                     // the power and data roles but it might take some time to apply
@@ -485,44 +507,37 @@
                     logAndPrint(Log.ERROR, pw, "Trying to set the USB port mode: "
                             + "portId=" + portId
                             + ", newMode=" + UsbPort.modeToString(newMode));
-                    PortRole newRole = new PortRole();
-                    newRole.type = PortRoleType.MODE;
-                    newRole.role = newMode;
                     try {
-                        mProxy.switchRole(portId, newRole);
-                    } catch (RemoteException e) {
+                        mUsbPortHal.switchMode(portId, toHalUsbMode(newMode), ++mTransactionId);
+                    } catch (Exception e) {
                         logAndPrintException(pw, "Failed to set the USB port mode: "
                                 + "portId=" + portId
-                                + ", newMode=" + UsbPort.modeToString(newRole.role), e);
+                                + ", newMode=" + UsbPort.modeToString(newMode), e);
                     }
                 } else {
                     // Change power and data role independently as needed.
                     if (currentPowerRole != newPowerRole) {
-                        PortRole newRole = new PortRole();
-                        newRole.type = PortRoleType.POWER_ROLE;
-                        newRole.role = newPowerRole;
                         try {
-                            mProxy.switchRole(portId, newRole);
-                        } catch (RemoteException e) {
+                            mUsbPortHal.switchPowerRole(portId, toHalUsbPowerRole(newPowerRole),
+                                    ++mTransactionId);
+                        } catch (Exception e) {
                             logAndPrintException(pw, "Failed to set the USB port power role: "
                                             + "portId=" + portId
                                             + ", newPowerRole=" + UsbPort.powerRoleToString
-                                            (newRole.role),
+                                            (newPowerRole),
                                     e);
                             return;
                         }
                     }
                     if (currentDataRole != newDataRole) {
-                        PortRole newRole = new PortRole();
-                        newRole.type = PortRoleType.DATA_ROLE;
-                        newRole.role = newDataRole;
                         try {
-                            mProxy.switchRole(portId, newRole);
-                        } catch (RemoteException e) {
+                            mUsbPortHal.switchDataRole(portId, toHalUsbDataRole(newDataRole),
+                                    ++mTransactionId);
+                        } catch (Exception e) {
                             logAndPrintException(pw, "Failed to set the USB port data role: "
                                             + "portId=" + portId
-                                            + ", newDataRole=" + UsbPort.dataRoleToString(newRole
-                                            .role),
+                                            + ", newDataRole=" + UsbPort.dataRoleToString
+                                            (newDataRole),
                                     e);
                         }
                     }
@@ -531,6 +546,15 @@
         }
     }
 
+    public void updatePorts(ArrayList<RawPortInfo> newPortInfo) {
+        Message message = mHandler.obtainMessage();
+        Bundle bundle = new Bundle();
+        bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
+        message.what = MSG_UPDATE_PORTS;
+        message.setData(bundle);
+        mHandler.sendMessage(message);
+    }
+
     public void addSimulatedPort(String portId, int supportedModes, IndentingPrintWriter pw) {
         synchronized (mLock) {
             if (mSimulatedPorts.containsKey(portId)) {
@@ -662,191 +686,12 @@
                 portInfo.dump(dump, "usb_ports", UsbPortManagerProto.USB_PORTS);
             }
 
-            dump.write("enable_usb_data_signaling", UsbPortManagerProto.ENABLE_USB_DATA_SIGNALING,
-                    mEnableUsbDataSignaling);
+            dump.write("usb_hal_version", UsbPortManagerProto.HAL_VERSION, getUsbHalVersion());
         }
 
         dump.end(token);
     }
 
-    private static class HALCallback extends IUsbCallback.Stub {
-        public IndentingPrintWriter pw;
-        public UsbPortManager portManager;
-
-        HALCallback(IndentingPrintWriter pw, UsbPortManager portManager) {
-            this.pw = pw;
-            this.portManager = portManager;
-        }
-
-        public void notifyPortStatusChange(
-                ArrayList<android.hardware.usb.V1_0.PortStatus> currentPortStatus, int retval) {
-            if (!portManager.mSystemReady) {
-                return;
-            }
-
-            if (retval != Status.SUCCESS) {
-                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
-                return;
-            }
-
-            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
-
-            for (android.hardware.usb.V1_0.PortStatus current : currentPortStatus) {
-                RawPortInfo temp = new RawPortInfo(current.portName,
-                        current.supportedModes, CONTAMINANT_PROTECTION_NONE,
-                        current.currentMode,
-                        current.canChangeMode, current.currentPowerRole,
-                        current.canChangePowerRole,
-                        current.currentDataRole, current.canChangeDataRole,
-                        false, CONTAMINANT_PROTECTION_NONE,
-                        false, CONTAMINANT_DETECTION_NOT_SUPPORTED);
-                newPortInfo.add(temp);
-                logAndPrint(Log.INFO, pw, "ClientCallback V1_0: " + current.portName);
-            }
-
-            Message message = portManager.mHandler.obtainMessage();
-            Bundle bundle = new Bundle();
-            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
-            message.what = MSG_UPDATE_PORTS;
-            message.setData(bundle);
-            portManager.mHandler.sendMessage(message);
-        }
-
-
-        public void notifyPortStatusChange_1_1(ArrayList<PortStatus_1_1> currentPortStatus,
-                int retval) {
-            if (!portManager.mSystemReady) {
-                return;
-            }
-
-            if (retval != Status.SUCCESS) {
-                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
-                return;
-            }
-
-            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
-
-            int numStatus = currentPortStatus.size();
-            for (int i = 0; i < numStatus; i++) {
-                PortStatus_1_1 current = currentPortStatus.get(i);
-                RawPortInfo temp = new RawPortInfo(current.status.portName,
-                        current.supportedModes, CONTAMINANT_PROTECTION_NONE,
-                        current.currentMode,
-                        current.status.canChangeMode, current.status.currentPowerRole,
-                        current.status.canChangePowerRole,
-                        current.status.currentDataRole, current.status.canChangeDataRole,
-                        false, CONTAMINANT_PROTECTION_NONE,
-                        false, CONTAMINANT_DETECTION_NOT_SUPPORTED);
-                newPortInfo.add(temp);
-                logAndPrint(Log.INFO, pw, "ClientCallback V1_1: " + current.status.portName);
-            }
-
-            Message message = portManager.mHandler.obtainMessage();
-            Bundle bundle = new Bundle();
-            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
-            message.what = MSG_UPDATE_PORTS;
-            message.setData(bundle);
-            portManager.mHandler.sendMessage(message);
-        }
-
-        public void notifyPortStatusChange_1_2(
-                ArrayList<PortStatus> currentPortStatus, int retval) {
-            if (!portManager.mSystemReady) {
-                return;
-            }
-
-            if (retval != Status.SUCCESS) {
-                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
-                return;
-            }
-
-            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
-
-            int numStatus = currentPortStatus.size();
-            for (int i = 0; i < numStatus; i++) {
-                PortStatus current = currentPortStatus.get(i);
-                RawPortInfo temp = new RawPortInfo(current.status_1_1.status.portName,
-                        current.status_1_1.supportedModes,
-                        current.supportedContaminantProtectionModes,
-                        current.status_1_1.currentMode,
-                        current.status_1_1.status.canChangeMode,
-                        current.status_1_1.status.currentPowerRole,
-                        current.status_1_1.status.canChangePowerRole,
-                        current.status_1_1.status.currentDataRole,
-                        current.status_1_1.status.canChangeDataRole,
-                        current.supportsEnableContaminantPresenceProtection,
-                        current.contaminantProtectionStatus,
-                        current.supportsEnableContaminantPresenceDetection,
-                        current.contaminantDetectionStatus);
-                newPortInfo.add(temp);
-                logAndPrint(Log.INFO, pw, "ClientCallback V1_2: "
-                        + current.status_1_1.status.portName);
-            }
-
-            Message message = portManager.mHandler.obtainMessage();
-            Bundle bundle = new Bundle();
-            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
-            message.what = MSG_UPDATE_PORTS;
-            message.setData(bundle);
-            portManager.mHandler.sendMessage(message);
-        }
-
-        public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
-            if (retval == Status.SUCCESS) {
-                logAndPrint(Log.INFO, pw, portName + " role switch successful");
-            } else {
-                logAndPrint(Log.ERROR, pw, portName + " role switch failed");
-            }
-        }
-    }
-
-    final class DeathRecipient implements HwBinder.DeathRecipient {
-        public IndentingPrintWriter pw;
-
-        DeathRecipient(IndentingPrintWriter pw) {
-            this.pw = pw;
-        }
-
-        @Override
-        public void serviceDied(long cookie) {
-            if (cookie == USB_HAL_DEATH_COOKIE) {
-                logAndPrint(Log.ERROR, pw, "Usb hal service died cookie: " + cookie);
-                synchronized (mLock) {
-                    mProxy = null;
-                }
-            }
-        }
-    }
-
-    final class ServiceNotification extends IServiceNotification.Stub {
-        @Override
-        public void onRegistration(String fqName, String name, boolean preexisting) {
-            logAndPrint(Log.INFO, null, "Usb hal service started " + fqName + " " + name);
-            connectToProxy(null);
-        }
-    }
-
-    private void connectToProxy(IndentingPrintWriter pw) {
-        synchronized (mLock) {
-            if (mProxy != null) {
-                return;
-            }
-
-            try {
-                mProxy = IUsb.getService();
-                mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
-                mProxy.setCallback(mHALCallback);
-                mProxy.queryPortStatus();
-                updateUsbHalVersion();
-            } catch (NoSuchElementException e) {
-                logAndPrintException(pw, "connectToProxy: usb hal service not found."
-                        + " Did the service fail to start?", e);
-            } catch (RemoteException e) {
-                logAndPrintException(pw, "connectToProxy: usb hal service not responding", e);
-            }
-        }
-    }
-
     /**
      * Simulated ports directly add the new roles to mSimulatedPorts before calling.
      * USB hal callback populates and sends the newPortInfo.
@@ -869,7 +714,8 @@
                         portInfo.supportsEnableContaminantPresenceProtection,
                         portInfo.contaminantProtectionStatus,
                         portInfo.supportsEnableContaminantPresenceDetection,
-                        portInfo.contaminantDetectionStatus, pw);
+                        portInfo.contaminantDetectionStatus,
+                        portInfo.usbDataEnabled, pw);
             }
         } else {
             for (RawPortInfo currentPortInfo : newPortInfo) {
@@ -881,7 +727,8 @@
                         currentPortInfo.supportsEnableContaminantPresenceProtection,
                         currentPortInfo.contaminantProtectionStatus,
                         currentPortInfo.supportsEnableContaminantPresenceDetection,
-                        currentPortInfo.contaminantDetectionStatus, pw);
+                        currentPortInfo.contaminantDetectionStatus,
+                        currentPortInfo.usbDataEnabled, pw);
             }
         }
 
@@ -917,6 +764,7 @@
             int contaminantProtectionStatus,
             boolean supportsEnableContaminantPresenceDetection,
             int contaminantDetectionStatus,
+            boolean usbDataEnabled,
             IndentingPrintWriter pw) {
         // Only allow mode switch capability for dual role ports.
         // Validate that the current mode matches the supported modes we expect.
@@ -975,7 +823,7 @@
                     currentPowerRole, canChangePowerRole,
                     currentDataRole, canChangeDataRole,
                     supportedRoleCombinations, contaminantProtectionStatus,
-                    contaminantDetectionStatus);
+                    contaminantDetectionStatus, usbDataEnabled);
             mPorts.put(portId, portInfo);
         } else {
             // Validate that ports aren't changing definition out from under us.
@@ -1012,7 +860,7 @@
                     currentPowerRole, canChangePowerRole,
                     currentDataRole, canChangeDataRole,
                     supportedRoleCombinations, contaminantProtectionStatus,
-                    contaminantDetectionStatus)) {
+                    contaminantDetectionStatus, usbDataEnabled)) {
                 portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
             } else {
                 portInfo.mDisposition = PortInfo.DISPOSITION_READY;
@@ -1141,14 +989,14 @@
         }
     }
 
-    private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
+    public static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
         Slog.println(priority, TAG, msg);
         if (pw != null) {
             pw.println(msg);
         }
     }
 
-    private static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) {
+    public static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) {
         Slog.e(TAG, msg, e);
         if (pw != null) {
             pw.println(msg + e);
@@ -1179,7 +1027,7 @@
     /**
      * Describes a USB port.
      */
-    private static final class PortInfo {
+    public static final class PortInfo {
         public static final int DISPOSITION_ADDED = 0;
         public static final int DISPOSITION_CHANGED = 1;
         public static final int DISPOSITION_READY = 2;
@@ -1224,7 +1072,7 @@
                     != supportedRoleCombinations) {
                 mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                         supportedRoleCombinations, UsbPortStatus.CONTAMINANT_PROTECTION_NONE,
-                        UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED);
+                        UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED, true);
                 dispositionChanged = true;
             }
 
@@ -1243,7 +1091,7 @@
                 int currentPowerRole, boolean canChangePowerRole,
                 int currentDataRole, boolean canChangeDataRole,
                 int supportedRoleCombinations, int contaminantProtectionStatus,
-                int contaminantDetectionStatus) {
+                int contaminantDetectionStatus, boolean usbDataEnabled) {
             boolean dispositionChanged = false;
 
             mCanChangeMode = canChangeMode;
@@ -1258,10 +1106,12 @@
                     || mUsbPortStatus.getContaminantProtectionStatus()
                     != contaminantProtectionStatus
                     || mUsbPortStatus.getContaminantDetectionStatus()
-                    != contaminantDetectionStatus) {
+                    != contaminantDetectionStatus
+                    || mUsbPortStatus.getUsbDataStatus()
+                    != usbDataEnabled){
                 mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                         supportedRoleCombinations, contaminantProtectionStatus,
-                        contaminantDetectionStatus);
+                        contaminantDetectionStatus, usbDataEnabled);
                 dispositionChanged = true;
             }
 
@@ -1290,7 +1140,6 @@
                     UsbPortInfoProto.CONNECTED_AT_MILLIS, mConnectedAtMillis);
             dump.write("last_connect_duration_millis",
                     UsbPortInfoProto.LAST_CONNECT_DURATION_MILLIS, mLastConnectDurationMillis);
-
             dump.end(token);
         }
 
@@ -1304,115 +1153,4 @@
                     + ", lastConnectDurationMillis=" + mLastConnectDurationMillis;
         }
     }
-
-    /**
-     * Used for storing the raw data from the kernel
-     * Values of the member variables mocked directly incase of emulation.
-     */
-    private static final class RawPortInfo implements Parcelable {
-        public final String portId;
-        public final int supportedModes;
-        public final int supportedContaminantProtectionModes;
-        public int currentMode;
-        public boolean canChangeMode;
-        public int currentPowerRole;
-        public boolean canChangePowerRole;
-        public int currentDataRole;
-        public boolean canChangeDataRole;
-        public boolean supportsEnableContaminantPresenceProtection;
-        public int contaminantProtectionStatus;
-        public boolean supportsEnableContaminantPresenceDetection;
-        public int contaminantDetectionStatus;
-
-        RawPortInfo(String portId, int supportedModes) {
-            this.portId = portId;
-            this.supportedModes = supportedModes;
-            this.supportedContaminantProtectionModes = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
-            this.supportsEnableContaminantPresenceProtection = false;
-            this.contaminantProtectionStatus = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
-            this.supportsEnableContaminantPresenceDetection = false;
-            this.contaminantDetectionStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
-        }
-
-        RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes,
-                int currentMode, boolean canChangeMode,
-                int currentPowerRole, boolean canChangePowerRole,
-                int currentDataRole, boolean canChangeDataRole,
-                boolean supportsEnableContaminantPresenceProtection,
-                int contaminantProtectionStatus,
-                boolean supportsEnableContaminantPresenceDetection,
-                int contaminantDetectionStatus) {
-            this.portId = portId;
-            this.supportedModes = supportedModes;
-            this.supportedContaminantProtectionModes = supportedContaminantProtectionModes;
-            this.currentMode = currentMode;
-            this.canChangeMode = canChangeMode;
-            this.currentPowerRole = currentPowerRole;
-            this.canChangePowerRole = canChangePowerRole;
-            this.currentDataRole = currentDataRole;
-            this.canChangeDataRole = canChangeDataRole;
-            this.supportsEnableContaminantPresenceProtection =
-                    supportsEnableContaminantPresenceProtection;
-            this.contaminantProtectionStatus = contaminantProtectionStatus;
-            this.supportsEnableContaminantPresenceDetection =
-                    supportsEnableContaminantPresenceDetection;
-            this.contaminantDetectionStatus = contaminantDetectionStatus;
-        }
-
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(portId);
-            dest.writeInt(supportedModes);
-            dest.writeInt(supportedContaminantProtectionModes);
-            dest.writeInt(currentMode);
-            dest.writeByte((byte) (canChangeMode ? 1 : 0));
-            dest.writeInt(currentPowerRole);
-            dest.writeByte((byte) (canChangePowerRole ? 1 : 0));
-            dest.writeInt(currentDataRole);
-            dest.writeByte((byte) (canChangeDataRole ? 1 : 0));
-            dest.writeBoolean(supportsEnableContaminantPresenceProtection);
-            dest.writeInt(contaminantProtectionStatus);
-            dest.writeBoolean(supportsEnableContaminantPresenceDetection);
-            dest.writeInt(contaminantDetectionStatus);
-        }
-
-        public static final Parcelable.Creator<RawPortInfo> CREATOR =
-                new Parcelable.Creator<RawPortInfo>() {
-            @Override
-            public RawPortInfo createFromParcel(Parcel in) {
-                String id = in.readString();
-                int supportedModes = in.readInt();
-                int supportedContaminantProtectionModes = in.readInt();
-                int currentMode = in.readInt();
-                boolean canChangeMode = in.readByte() != 0;
-                int currentPowerRole = in.readInt();
-                boolean canChangePowerRole = in.readByte() != 0;
-                int currentDataRole = in.readInt();
-                boolean canChangeDataRole = in.readByte() != 0;
-                boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
-                int contaminantProtectionStatus = in.readInt();
-                boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
-                int contaminantDetectionStatus = in.readInt();
-                return new RawPortInfo(id, supportedModes,
-                        supportedContaminantProtectionModes, currentMode, canChangeMode,
-                        currentPowerRole, canChangePowerRole,
-                        currentDataRole, canChangeDataRole,
-                        supportsEnableContaminantPresenceProtection,
-                        contaminantProtectionStatus,
-                        supportsEnableContaminantPresenceDetection,
-                        contaminantDetectionStatus);
-            }
-
-            @Override
-            public RawPortInfo[] newArray(int size) {
-                return new RawPortInfo[size];
-            }
-        };
-    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 3d3538d..28227fc 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.usb;
 
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST;
 import static android.hardware.usb.UsbPortStatus.MODE_DFP;
@@ -35,6 +36,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.hardware.usb.IUsbManager;
+import android.hardware.usb.IUsbOperationInternal;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbDevice;
@@ -44,6 +46,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.usb.UsbServiceDumpProto;
@@ -762,19 +765,30 @@
     }
 
     @Override
-    public boolean enableUsbDataSignal(boolean enable) {
+    public boolean enableUsbData(String portId, boolean enable, int operationId,
+            IUsbOperationInternal callback) {
+        Objects.requireNonNull(portId, "enableUsbData: portId must not be null. opId:"
+                + operationId);
+        Objects.requireNonNull(callback, "enableUsbData: callback must not be null. opId:"
+                + operationId);
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
-
         final long ident = Binder.clearCallingIdentity();
+        boolean wait;
         try {
             if (mPortManager != null) {
-                return mPortManager.enableUsbDataSignal(enable);
+                wait = mPortManager.enableUsbData(portId, enable, operationId, callback, null);
             } else {
-                return false;
+                wait = false;
+                try {
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "enableUsbData: Failed to call onOperationComplete", e);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
+        return wait;
     }
 
     @Override
diff --git a/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java
new file mode 100644
index 0000000..9c6cbbd
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.port;
+
+import android.hardware.usb.UsbPortStatus;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Used for storing the raw data from the HAL.
+ * Values of the member variables mocked directly in case of emulation.
+ */
+public final class RawPortInfo implements Parcelable {
+    public final String portId;
+    public final int supportedModes;
+    public final int supportedContaminantProtectionModes;
+    public int currentMode;
+    public boolean canChangeMode;
+    public int currentPowerRole;
+    public boolean canChangePowerRole;
+    public int currentDataRole;
+    public boolean canChangeDataRole;
+    public boolean supportsEnableContaminantPresenceProtection;
+    public int contaminantProtectionStatus;
+    public boolean supportsEnableContaminantPresenceDetection;
+    public int contaminantDetectionStatus;
+    public boolean usbDataEnabled;
+
+    public RawPortInfo(String portId, int supportedModes) {
+        this.portId = portId;
+        this.supportedModes = supportedModes;
+        this.supportedContaminantProtectionModes = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+        this.supportsEnableContaminantPresenceProtection = false;
+        this.contaminantProtectionStatus = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+        this.supportsEnableContaminantPresenceDetection = false;
+        this.contaminantDetectionStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
+        this.usbDataEnabled = true;
+    }
+
+    public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes,
+            int currentMode, boolean canChangeMode,
+            int currentPowerRole, boolean canChangePowerRole,
+            int currentDataRole, boolean canChangeDataRole,
+            boolean supportsEnableContaminantPresenceProtection,
+            int contaminantProtectionStatus,
+            boolean supportsEnableContaminantPresenceDetection,
+            int contaminantDetectionStatus,
+            boolean usbDataEnabled) {
+        this.portId = portId;
+        this.supportedModes = supportedModes;
+        this.supportedContaminantProtectionModes = supportedContaminantProtectionModes;
+        this.currentMode = currentMode;
+        this.canChangeMode = canChangeMode;
+        this.currentPowerRole = currentPowerRole;
+        this.canChangePowerRole = canChangePowerRole;
+        this.currentDataRole = currentDataRole;
+        this.canChangeDataRole = canChangeDataRole;
+        this.supportsEnableContaminantPresenceProtection =
+                supportsEnableContaminantPresenceProtection;
+        this.contaminantProtectionStatus = contaminantProtectionStatus;
+        this.supportsEnableContaminantPresenceDetection =
+                supportsEnableContaminantPresenceDetection;
+        this.contaminantDetectionStatus = contaminantDetectionStatus;
+        this.usbDataEnabled = usbDataEnabled;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(portId);
+        dest.writeInt(supportedModes);
+        dest.writeInt(supportedContaminantProtectionModes);
+        dest.writeInt(currentMode);
+        dest.writeByte((byte) (canChangeMode ? 1 : 0));
+        dest.writeInt(currentPowerRole);
+        dest.writeByte((byte) (canChangePowerRole ? 1 : 0));
+        dest.writeInt(currentDataRole);
+        dest.writeByte((byte) (canChangeDataRole ? 1 : 0));
+        dest.writeBoolean(supportsEnableContaminantPresenceProtection);
+        dest.writeInt(contaminantProtectionStatus);
+        dest.writeBoolean(supportsEnableContaminantPresenceDetection);
+        dest.writeInt(contaminantDetectionStatus);
+        dest.writeBoolean(usbDataEnabled);
+    }
+
+    public static final Parcelable.Creator<RawPortInfo> CREATOR =
+            new Parcelable.Creator<RawPortInfo>() {
+        @Override
+        public RawPortInfo createFromParcel(Parcel in) {
+            String id = in.readString();
+            int supportedModes = in.readInt();
+            int supportedContaminantProtectionModes = in.readInt();
+            int currentMode = in.readInt();
+            boolean canChangeMode = in.readByte() != 0;
+            int currentPowerRole = in.readInt();
+            boolean canChangePowerRole = in.readByte() != 0;
+            int currentDataRole = in.readInt();
+            boolean canChangeDataRole = in.readByte() != 0;
+            boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
+            int contaminantProtectionStatus = in.readInt();
+            boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
+            int contaminantDetectionStatus = in.readInt();
+            boolean usbDataEnabled = in.readBoolean();
+            return new RawPortInfo(id, supportedModes,
+                    supportedContaminantProtectionModes, currentMode, canChangeMode,
+                    currentPowerRole, canChangePowerRole,
+                    currentDataRole, canChangeDataRole,
+                    supportsEnableContaminantPresenceProtection,
+                    contaminantProtectionStatus,
+                    supportsEnableContaminantPresenceDetection,
+                    contaminantDetectionStatus, usbDataEnabled);
+        }
+
+        @Override
+        public RawPortInfo[] newArray(int size) {
+            return new RawPortInfo[size];
+        }
+    };
+}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
new file mode 100644
index 0000000..1efcd9c
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.port;
+
+import static android.hardware.usb.UsbManager.USB_HAL_V2_0;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_SUCCESS;
+
+import static com.android.server.usb.UsbPortManager.logAndPrint;
+import static com.android.server.usb.UsbPortManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.IUsb;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
+import android.hardware.usb.PortMode;
+import android.hardware.usb.Status;
+import android.hardware.usb.IUsbCallback;
+import android.hardware.usb.PortRole;
+import android.hardware.usb.PortStatus;
+import android.os.ServiceManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbPortManager;
+import com.android.server.usb.hal.port.RawPortInfo;
+
+import java.util.ArrayList;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
+/**
+ * Implements the methods to interact with AIDL USB HAL.
+ */
+public final class UsbPortAidl implements UsbPortHal {
+    private static final String TAG = UsbPortAidl.class.getSimpleName();
+    private static final String USB_AIDL_SERVICE =
+            "android.hardware.usb.IUsb/default";
+    private static final LongSparseArray<IUsbOperationInternal>
+                sCallbacks = new LongSparseArray<>();
+    // Proxy object for the usb hal daemon.
+    @GuardedBy("mLock")
+    private IUsb mProxy;
+    private UsbPortManager mPortManager;
+    public IndentingPrintWriter mPw;
+    // Mutex for all mutable shared state.
+    private final Object mLock = new Object();
+    // Callback when the UsbPort status is changed by the kernel.
+    private HALCallback mHALCallback;
+    private IBinder mBinder;
+    private boolean mSystemReady;
+    private long mTransactionId;
+
+    public @UsbHalVersion int getUsbHalVersion() throws RemoteException {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                throw new RemoteException("IUsb not initialized yet");
+            }
+        }
+        logAndPrint(Log.INFO, null, "USB HAL AIDL version: USB_HAL_V2_0");
+        return USB_HAL_V2_0;
+    }
+
+    @Override
+    public void systemReady() {
+        mSystemReady = true;
+    }
+
+    public void serviceDied() {
+        logAndPrint(Log.ERROR, mPw, "Usb AIDL hal service died");
+        synchronized (mLock) {
+            mProxy = null;
+        }
+        connectToProxy(null);
+    }
+
+    private void connectToProxy(IndentingPrintWriter pw) {
+        synchronized (mLock) {
+            if (mProxy != null) {
+                return;
+            }
+
+            try {
+                mBinder = ServiceManager.waitForService(USB_AIDL_SERVICE);
+                mProxy = IUsb.Stub.asInterface(mBinder);
+                mBinder.linkToDeath(this::serviceDied, 0);
+                mProxy.setCallback(mHALCallback);
+                mProxy.queryPortStatus(++mTransactionId);
+            } catch (NoSuchElementException e) {
+                logAndPrintException(pw, "connectToProxy: usb hal service not found."
+                        + " Did the service fail to start?", e);
+            } catch (RemoteException e) {
+                logAndPrintException(pw, "connectToProxy: usb hal service not responding", e);
+            }
+        }
+    }
+
+    static boolean isServicePresent(IndentingPrintWriter pw) {
+        try {
+            return ServiceManager.isDeclared(USB_AIDL_SERVICE);
+        } catch (NoSuchElementException e) {
+            logAndPrintException(pw, "connectToProxy: usb Aidl hal service not found.", e);
+        }
+
+        return false;
+    }
+
+    public UsbPortAidl(UsbPortManager portManager, IndentingPrintWriter pw) {
+        mPortManager = Objects.requireNonNull(portManager);
+        mPw = pw;
+        mHALCallback = new HALCallback(null, mPortManager, this);
+        connectToProxy(mPw);
+    }
+
+    @Override
+    public void enableContaminantPresenceDetection(String portName, boolean enable,
+            long operationID) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry ! opID: "
+                        + operationID);
+                return;
+            }
+
+            try {
+                // Oneway call into the hal. Use the castFrom method from HIDL.
+                mProxy.enableContaminantPresenceDetection(portName, enable, operationID);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set contaminant detection. opID:"
+                        + operationID, e);
+            }
+        }
+    }
+
+    @Override
+    public void queryPortStatus(long operationID) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry ! opID:"
+                        + operationID);
+                return;
+            }
+
+            try {
+                mProxy.queryPortStatus(operationID);
+            } catch (RemoteException e) {
+                logAndPrintException(null, "ServiceStart: Failed to query port status. opID:"
+                        + operationID, e);
+            }
+       }
+    }
+
+    @Override
+    public void switchMode(String portId, @HalUsbPortMode int newMode, long operationID) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry ! opID:"
+                        + operationID);
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.setMode((byte)newMode);
+            try {
+                mProxy.switchRole(portId, newRole, operationID);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB port mode: "
+                        + "portId=" + portId
+                        + ", newMode=" + UsbPort.modeToString(newMode)
+                        + "opID:" + operationID, e);
+            }
+        }
+    }
+
+    @Override
+    public void switchPowerRole(String portId, @HalUsbPowerRole int newPowerRole,
+            long operationID) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry ! opID:"
+                        + operationID);
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.setPowerRole((byte)newPowerRole);
+            try {
+                mProxy.switchRole(portId, newRole, operationID);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB power role: portId=" + portId
+                        + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)
+                        + "opID:" + operationID, e);
+            }
+        }
+    }
+
+    @Override
+    public void switchDataRole(String portId, @HalUsbDataRole int newDataRole, long operationID) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry ! opID:"
+                        + operationID);
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.setDataRole((byte)newDataRole);
+            try {
+                mProxy.switchRole(portId, newRole, operationID);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB data role: portId=" + portId
+                        + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole)
+                        + "opID:" + operationID, e);
+            }
+        }
+    }
+
+    @Override
+    public boolean enableUsbData(String portName, boolean enable, long operationID,
+            IUsbOperationInternal callback) {
+        Objects.requireNonNull(portName);
+        Objects.requireNonNull(callback);
+        long key = operationID;
+        synchronized (mLock) {
+            try {
+                if (mProxy == null) {
+                    logAndPrint(Log.ERROR, mPw,
+                            "enableUsbData: Proxy is null. Retry !opID:"
+                            + operationID);
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                    return false;
+                }
+                while (sCallbacks.get(key) != null) {
+                    key = ThreadLocalRandom.current().nextInt();
+                }
+                if (key != operationID) {
+                    logAndPrint(Log.INFO, mPw, "enableUsbData: operationID exists ! opID:"
+                            + operationID + " key:" + key);
+                }
+                try {
+                    sCallbacks.put(key, callback);
+                    mProxy.enableUsbData(portName, enable, key);
+                } catch (RemoteException e) {
+                    logAndPrintException(mPw,
+                            "enableUsbData: Failed to invoke enableUsbData: portID="
+                            + portName + "opID:" + operationID, e);
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                    sCallbacks.remove(key);
+                    return false;
+                }
+            } catch (RemoteException e) {
+                logAndPrintException(mPw,
+                        "enableUsbData: Failed to call onOperationComplete portID="
+                        + portName + "opID:" + operationID, e);
+                sCallbacks.remove(key);
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private static class HALCallback extends IUsbCallback.Stub {
+        public IndentingPrintWriter mPw;
+        public UsbPortManager mPortManager;
+        public UsbPortAidl mUsbPortAidl;
+
+        HALCallback(IndentingPrintWriter pw, UsbPortManager portManager, UsbPortAidl usbPortAidl) {
+            this.mPw = pw;
+            this.mPortManager = portManager;
+            this.mUsbPortAidl = usbPortAidl;
+        }
+
+        /**
+         * Converts from AIDL defined mode constants to UsbPortStatus constants.
+         * AIDL does not gracefully support bitfield when combined with enums.
+         */
+        private int toPortMode(byte aidlPortMode) {
+            switch (aidlPortMode) {
+                case PortMode.NONE:
+                    return UsbPortStatus.MODE_NONE;
+                case PortMode.UFP:
+                    return UsbPortStatus.MODE_UFP;
+                case PortMode.DFP:
+                    return UsbPortStatus.MODE_DFP;
+                case PortMode.DRP:
+                    return UsbPortStatus.MODE_DUAL;
+                case PortMode.AUDIO_ACCESSORY:
+                    return UsbPortStatus.MODE_AUDIO_ACCESSORY;
+                case PortMode.DEBUG_ACCESSORY:
+                    return UsbPortStatus.MODE_DEBUG_ACCESSORY;
+                default:
+                    UsbPortManager.logAndPrint(Log.ERROR, mPw, "Unrecognized aidlPortMode:"
+                            + aidlPortMode);
+                    return UsbPortStatus.MODE_NONE;
+            }
+        }
+
+        private int toSupportedModes(byte[] aidlPortModes) {
+            int supportedModes = UsbPortStatus.MODE_NONE;
+
+            for (byte aidlPortMode : aidlPortModes) {
+                supportedModes |= toPortMode(aidlPortMode);
+            }
+
+            return supportedModes;
+        }
+
+        /**
+         * Converts from AIDL defined contaminant protection constants to UsbPortStatus constants.
+         * AIDL does not gracefully support bitfield when combined with enums.
+         * Common to both ContaminantProtectionMode and ContaminantProtectionStatus.
+         */
+        private int toContaminantProtectionStatus(byte aidlContaminantProtection) {
+            switch (aidlContaminantProtection) {
+                case ContaminantProtectionStatus.NONE:
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+                case ContaminantProtectionStatus.FORCE_SINK:
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_SINK;
+                case ContaminantProtectionStatus.FORCE_SOURCE:
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_SOURCE;
+                case ContaminantProtectionStatus.FORCE_DISABLE:
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_FORCE_DISABLE;
+                case ContaminantProtectionStatus.DISABLED:
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_DISABLED;
+                default:
+                    UsbPortManager.logAndPrint(Log.ERROR, mPw,
+                            "Unrecognized aidlContaminantProtection:"
+                            + aidlContaminantProtection);
+                    return UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+            }
+        }
+
+        private int toSupportedContaminantProtectionModes(byte[] aidlModes) {
+            int supportedContaminantProtectionModes = UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+
+            for (byte aidlMode : aidlModes) {
+                supportedContaminantProtectionModes |= toContaminantProtectionStatus(aidlMode);
+            }
+
+            return supportedContaminantProtectionModes;
+        }
+
+        @Override
+        public void notifyPortStatusChange(
+               android.hardware.usb.PortStatus[] currentPortStatus, int retval) {
+            if (!mUsbPortAidl.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
+
+            int numStatus = currentPortStatus.length;
+            for (int i = 0; i < numStatus; i++) {
+                PortStatus current = currentPortStatus[i];
+                RawPortInfo temp = new RawPortInfo(current.portName,
+                        toSupportedModes(current.supportedModes),
+                        toSupportedContaminantProtectionModes(current
+                                .supportedContaminantProtectionModes),
+                        toPortMode(current.currentMode),
+                        current.canChangeMode,
+                        current.currentPowerRole,
+                        current.canChangePowerRole,
+                        current.currentDataRole,
+                        current.canChangeDataRole,
+                        current.supportsEnableContaminantPresenceProtection,
+                        toContaminantProtectionStatus(current.contaminantProtectionStatus),
+                        current.supportsEnableContaminantPresenceDetection,
+                        current.contaminantDetectionStatus,
+                        current.usbDataEnabled);
+                newPortInfo.add(temp);
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback AIDL V1: "
+                        + current.portName);
+            }
+            mPortManager.updatePorts(newPortInfo);
+        }
+
+        @Override
+        public void notifyRoleSwitchStatus(String portName, PortRole role, int retval,
+                long operationID) {
+            if (retval == Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.INFO, mPw, portName
+                        + " role switch successful. opID:"
+                        + operationID);
+            } else {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, portName + " role switch failed. err:"
+                        + retval
+                        + "opID:" + operationID);
+            }
+        }
+
+        @Override
+        public void notifyQueryPortStatus(String portName, int retval, long operationID) {
+            if (retval == Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.INFO, mPw, portName + ": opID:"
+                        + operationID + " successful");
+            } else {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, portName + ": opID:"
+                        + operationID + " failed. err:" + retval);
+            }
+        }
+
+        @Override
+        public void notifyEnableUsbDataStatus(String portName, boolean enable, int retval,
+                long operationID) {
+            if (retval == Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "notifyEnableUsbDataStatus:"
+                        + portName + ": opID:"
+                        + operationID + " enable:" + enable);
+            } else {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, portName
+                        + "notifyEnableUsbDataStatus: opID:"
+                        + operationID + " failed. err:" + retval);
+            }
+            try {
+                sCallbacks.get(operationID).onOperationComplete(retval == Status.SUCCESS
+                        ? USB_OPERATION_SUCCESS
+                        : USB_OPERATION_ERROR_INTERNAL);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw,
+                        "notifyEnableUsbDataStatus: Failed to call onOperationComplete",
+                        e);
+            }
+        }
+
+        @Override
+        public void notifyContaminantEnabledStatus(String portName, boolean enable, int retval,
+                long operationID) {
+            if (retval == Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "notifyContaminantEnabledStatus:"
+                        + portName + ": opID:"
+                        + operationID + " enable:" + enable);
+            } else {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, portName
+                        + "notifyContaminantEnabledStatus: opID:"
+                        + operationID + " failed. err:" + retval);
+            }
+        }
+
+        @Override
+        public String getInterfaceHash() {
+            return IUsbCallback.HASH;
+        }
+
+        @Override
+        public int getInterfaceVersion() {
+            return IUsbCallback.VERSION;
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
new file mode 100644
index 0000000..e7f9bc2
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.port;
+
+import android.annotation.IntDef;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.os.RemoteException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.String;
+
+/**
+ * @hide
+ */
+public interface UsbPortHal {
+    /**
+     * Power role: This USB port can act as a source (provide power).
+     * @hide
+     */
+    public static final int HAL_POWER_ROLE_SOURCE = 1;
+
+    /**
+     * Power role: This USB port can act as a sink (receive power).
+     * @hide
+     */
+    public static final int HAL_POWER_ROLE_SINK = 2;
+
+    @IntDef(prefix = { "HAL_POWER_ROLE_" }, value = {
+            HAL_POWER_ROLE_SOURCE,
+            HAL_POWER_ROLE_SINK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbPowerRole{}
+
+    /**
+     * Data role: This USB port can act as a host (access data services).
+     * @hide
+     */
+    public static final int HAL_DATA_ROLE_HOST = 1;
+
+    /**
+     * Data role: This USB port can act as a device (offer data services).
+     * @hide
+     */
+    public static final int HAL_DATA_ROLE_DEVICE = 2;
+
+    @IntDef(prefix = { "HAL_DATA_ROLE_" }, value = {
+            HAL_DATA_ROLE_HOST,
+            HAL_DATA_ROLE_DEVICE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbDataRole{}
+
+    /**
+     * This USB port can act as a downstream facing port (host).
+     *
+     * @hide
+     */
+    public static final int HAL_MODE_DFP = 1;
+
+    /**
+     * This USB port can act as an upstream facing port (device).
+     *
+     * @hide
+     */
+    public static final int HAL_MODE_UFP = 2;
+    @IntDef(prefix = { "HAL_MODE_" }, value = {
+            HAL_MODE_DFP,
+            HAL_MODE_UFP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbPortMode{}
+
+    /**
+     * UsbPortManager would call this when the system is done booting.
+     */
+    public void systemReady();
+
+    /**
+     * Invoked to enable/disable contaminant presence detection on the USB port.
+     *
+     * @param portName Port Identifier.
+     * @param enable Enable contaminant presence detection when true.
+     *               Disable when false.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void enableContaminantPresenceDetection(String portName, boolean enable,
+            long transactionId);
+
+    /**
+     * Invoked to query port status of all the ports.
+     *
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void queryPortStatus(long transactionId);
+
+    /**
+     * Invoked to switch USB port mode.
+     *
+     * @param portName Port Identifier.
+     * @param mode New mode that the port is switching into.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void switchMode(String portName, @HalUsbPortMode int mode, long transactionId);
+
+    /**
+     * Invoked to switch USB port power role.
+     *
+     * @param portName Port Identifier.
+     * @param powerRole New power role that the port is switching into.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void switchPowerRole(String portName, @HalUsbPowerRole int powerRole,
+            long transactionId);
+
+    /**
+     * Invoked to switch USB port data role.
+     *
+     * @param portName Port Identifier.
+     * @param dataRole New data role that the port is switching into.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void switchDataRole(String portName, @HalUsbDataRole int dataRole, long transactionId);
+
+    /**
+     * Invoked to query the version of current hal implementation.
+     */
+    public @UsbHalVersion int getUsbHalVersion() throws RemoteException;
+
+    /**
+     * Invoked to enable/disable UsbData on the specified port.
+     *
+     * @param portName Port Identifier.
+     * @param enable Enable USB data when true.
+     *               Disable when false.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     * @param callback callback object to be invoked to invoke the status of the operation upon
+     *                 completion.
+     * @param callback callback object to be invoked when the operation is complete.
+     * @return True when the operation is asynchronous. The caller of
+     *         {@link UsbOperationCallbackInternal} must therefore call
+     *         {@link UsbOperationCallbackInternal#waitForOperationComplete} for processing
+     *         the result.
+     *         False when the operation is synchronous. Caller can proceed reading the result
+     *         through {@link UsbOperationCallbackInternal#getStatus}
+     */
+    public boolean enableUsbData(String portName, boolean enable, long transactionId,
+            IUsbOperationInternal callback);
+}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHalInstance.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHalInstance.java
new file mode 100644
index 0000000..41f9fae
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHalInstance.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.port;
+
+import static com.android.server.usb.UsbPortManager.logAndPrint;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.hal.port.UsbPortHidl;
+import com.android.server.usb.hal.port.UsbPortAidl;
+import com.android.server.usb.UsbPortManager;
+
+import android.util.Log;
+/**
+ * Helper class that queries the underlying hal layer to populate UsbPortHal instance.
+ */
+public final class UsbPortHalInstance {
+
+    public static UsbPortHal getInstance(UsbPortManager portManager, IndentingPrintWriter pw) {
+
+        logAndPrint(Log.DEBUG, null, "Querying USB HAL version");
+        if (UsbPortHidl.isServicePresent(null)) {
+            logAndPrint(Log.INFO, null, "USB HAL HIDL present");
+            return new UsbPortHidl(portManager, pw);
+        }
+        if (UsbPortAidl.isServicePresent(null)) {
+            logAndPrint(Log.INFO, null, "USB HAL AIDL present");
+            return new UsbPortAidl(portManager, pw);
+        }
+
+        return null;
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
new file mode 100644
index 0000000..00d0d06
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.port;
+
+import static android.hardware.usb.UsbManager.USB_HAL_NOT_SUPPORTED;
+import static android.hardware.usb.UsbManager.USB_HAL_V1_0;
+import static android.hardware.usb.UsbManager.USB_HAL_V1_1;
+import static android.hardware.usb.UsbManager.USB_HAL_V1_2;
+import static android.hardware.usb.UsbManager.USB_HAL_V1_3;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_NOT_SUPPORTED;
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_SUCCESS;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED;
+import static android.hardware.usb.UsbPortStatus.CONTAMINANT_PROTECTION_NONE;
+import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE;
+import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST;
+import static android.hardware.usb.UsbPortStatus.MODE_DFP;
+import static android.hardware.usb.UsbPortStatus.MODE_DUAL;
+import static android.hardware.usb.UsbPortStatus.MODE_UFP;
+import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
+import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
+
+import static com.android.server.usb.UsbPortManager.logAndPrint;
+import static com.android.server.usb.UsbPortManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.V1_0.IUsb;
+import android.hardware.usb.V1_0.PortRoleType;
+import android.hardware.usb.V1_0.Status;
+import android.hardware.usb.V1_1.PortStatus_1_1;
+import android.hardware.usb.V1_2.IUsbCallback;
+import android.hardware.usb.V1_0.PortRole;
+import android.hardware.usb.V1_2.PortStatus;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.IHwBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbPortManager;
+import com.android.server.usb.hal.port.RawPortInfo;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+/**
+ *
+ */
+public final class UsbPortHidl implements UsbPortHal {
+    private static final String TAG = UsbPortHidl.class.getSimpleName();
+    // Cookie sent for usb hal death notification.
+    private static final int USB_HAL_DEATH_COOKIE = 1000;
+    // Proxy object for the usb hal daemon.
+    @GuardedBy("mLock")
+    private IUsb mProxy;
+    private UsbPortManager mPortManager;
+    public IndentingPrintWriter mPw;
+    // Mutex for all mutable shared state.
+    private final Object mLock = new Object();
+    // Callback when the UsbPort status is changed by the kernel.
+    private HALCallback mHALCallback;
+    private boolean mSystemReady;
+    // Workaround since HIDL HAL versions report UsbDataEnabled status in UsbPortStatus;
+    private static boolean sUsbDataEnabled = true;
+
+    public @UsbHalVersion int getUsbHalVersion() throws RemoteException {
+        int version;
+        synchronized(mLock) {
+            if (mProxy == null) {
+                throw new RemoteException("IUsb not initialized yet");
+            }
+            if (android.hardware.usb.V1_3.IUsb.castFrom(mProxy) != null) {
+                version = USB_HAL_V1_3;
+            } else if (android.hardware.usb.V1_2.IUsb.castFrom(mProxy) != null) {
+                version = USB_HAL_V1_2;
+            } else if (android.hardware.usb.V1_1.IUsb.castFrom(mProxy) != null) {
+                version = USB_HAL_V1_1;
+            } else {
+                version = USB_HAL_V1_0;
+            }
+            logAndPrint(Log.INFO, null, "USB HAL HIDL version: " + version);
+            return version;
+        }
+    }
+
+    final class DeathRecipient implements IHwBinder.DeathRecipient {
+        public IndentingPrintWriter pw;
+
+        DeathRecipient(IndentingPrintWriter pw) {
+            this.pw = pw;
+        }
+
+        @Override
+        public void serviceDied(long cookie) {
+            if (cookie == USB_HAL_DEATH_COOKIE) {
+                logAndPrint(Log.ERROR, pw, "Usb hal service died cookie: " + cookie);
+                synchronized (mLock) {
+                    mProxy = null;
+                }
+            }
+        }
+    }
+
+    final class ServiceNotification extends IServiceNotification.Stub {
+        @Override
+        public void onRegistration(String fqName, String name, boolean preexisting) {
+            logAndPrint(Log.INFO, null, "Usb hal service started " + fqName + " " + name);
+            connectToProxy(null);
+        }
+    }
+
+    private void connectToProxy(IndentingPrintWriter pw) {
+        synchronized (mLock) {
+            if (mProxy != null) {
+                return;
+            }
+
+            try {
+                mProxy = IUsb.getService();
+                mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
+                mProxy.setCallback(mHALCallback);
+                mProxy.queryPortStatus();
+                //updateUsbHalVersion();
+            } catch (NoSuchElementException e) {
+                logAndPrintException(pw, "connectToProxy: usb hal service not found."
+                        + " Did the service fail to start?", e);
+            } catch (RemoteException e) {
+                logAndPrintException(pw, "connectToProxy: usb hal service not responding", e);
+            }
+        }
+    }
+
+    @Override
+    public void systemReady() {
+        mSystemReady = true;
+    }
+
+    static boolean isServicePresent(IndentingPrintWriter pw) {
+        try {
+            IUsb.getService(true);
+        } catch (NoSuchElementException e) {
+            logAndPrintException(pw, "connectToProxy: usb hidl hal service not found.", e);
+            return false;
+        } catch (RemoteException e) {
+            logAndPrintException(pw, "IUSB hal service present but failed to get service", e);
+        }
+
+        return true;
+    }
+
+    public UsbPortHidl(UsbPortManager portManager, IndentingPrintWriter pw) {
+        mPortManager = Objects.requireNonNull(portManager);
+        mPw = pw;
+        mHALCallback = new HALCallback(null, mPortManager, this);
+        try {
+            ServiceNotification serviceNotification = new ServiceNotification();
+
+            boolean ret = IServiceManager.getService()
+                    .registerForNotifications("android.hardware.usb@1.0::IUsb",
+                            "", serviceNotification);
+            if (!ret) {
+                logAndPrint(Log.ERROR, null,
+                        "Failed to register service start notification");
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(null,
+                    "Failed to register service start notification", e);
+            return;
+        }
+        connectToProxy(mPw);
+    }
+
+    @Override
+    public void enableContaminantPresenceDetection(String portName, boolean enable,
+            long transactionId) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry !");
+                return;
+            }
+
+            try {
+                // Oneway call into the hal. Use the castFrom method from HIDL.
+                android.hardware.usb.V1_2.IUsb proxy =
+                        android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
+                proxy.enableContaminantPresenceDetection(portName, enable);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set contaminant detection", e);
+            } catch (ClassCastException e)  {
+                logAndPrintException(mPw, "Method only applicable to V1.2 or above implementation",
+                    e);
+            }
+        }
+    }
+
+    @Override
+    public void queryPortStatus(long transactionId) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry !");
+                return;
+            }
+
+            try {
+                mProxy.queryPortStatus();
+            } catch (RemoteException e) {
+                logAndPrintException(null, "ServiceStart: Failed to query port status", e);
+            }
+       }
+    }
+
+    @Override
+    public void switchMode(String portId, @HalUsbPortMode int newMode, long transactionId) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry !");
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.type = PortRoleType.MODE;
+            newRole.role = newMode;
+            try {
+                mProxy.switchRole(portId, newRole);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB port mode: "
+                    + "portId=" + portId
+                    + ", newMode=" + UsbPort.modeToString(newRole.role), e);
+            }
+        }
+    }
+
+    @Override
+    public void switchPowerRole(String portId, @HalUsbPowerRole int newPowerRole,
+            long transactionId) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry !");
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.type = PortRoleType.POWER_ROLE;
+            newRole.role = newPowerRole;
+            try {
+                mProxy.switchRole(portId, newRole);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB power role: portId=" + portId
+                    + ", newPowerRole=" + UsbPort.powerRoleToString(newRole.role), e);
+            }
+        }
+    }
+
+    @Override
+    public void switchDataRole(String portId, @HalUsbDataRole int newDataRole, long transactionId) {
+        synchronized (mLock) {
+            if (mProxy == null) {
+                logAndPrint(Log.ERROR, mPw, "Proxy is null. Retry !");
+                return;
+            }
+
+            PortRole newRole = new PortRole();
+            newRole.type = PortRoleType.DATA_ROLE;
+            newRole.role = newDataRole;
+            try {
+                mProxy.switchRole(portId, newRole);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to set the USB data role: portId=" + portId
+                    + ", newDataRole=" + UsbPort.dataRoleToString(newRole.role), e);
+            }
+        }
+    }
+
+    @Override
+    public boolean enableUsbData(String portName, boolean enable, long transactionId,
+            IUsbOperationInternal callback) {
+        int halVersion;
+
+        try {
+            halVersion = getUsbHalVersion();
+        } catch (RemoteException e) {
+            logAndPrintException(mPw, "Failed to query USB HAL version. opID:"
+                    + transactionId
+                    + " portId:" + portName, e);
+            return false;
+        }
+
+        if (halVersion != USB_HAL_V1_3) {
+            try {
+                callback.onOperationComplete(USB_OPERATION_ERROR_NOT_SUPPORTED);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed to call onOperationComplete. opID:"
+                        + transactionId
+                        + " portId:" + portName, e);
+            }
+            return false;
+        }
+
+        boolean success;
+        synchronized(mLock) {
+            try {
+                android.hardware.usb.V1_3.IUsb proxy
+                        = android.hardware.usb.V1_3.IUsb.castFrom(mProxy);
+                success = proxy.enableUsbDataSignal(enable);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw, "Failed enableUsbData: opId:" + transactionId
+                        + " portId=" + portName , e);
+                try {
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                } catch (RemoteException r) {
+                    logAndPrintException(mPw, "Failed to call onOperationComplete. opID:"
+                            + transactionId
+                            + " portId:" + portName, r);
+                }
+                return false;
+            }
+        }
+        if (success) {
+            sUsbDataEnabled = enable;
+        }
+
+        try {
+            callback.onOperationComplete(success
+                    ? USB_OPERATION_SUCCESS
+                    : USB_OPERATION_ERROR_INTERNAL);
+        } catch (RemoteException r) {
+            logAndPrintException(mPw, "Failed to call onOperationComplete. opID:"
+                + transactionId
+                + " portId:" + portName, r);
+        }
+        return false;
+    }
+
+    private static class HALCallback extends IUsbCallback.Stub {
+        public IndentingPrintWriter mPw;
+        public UsbPortManager mPortManager;
+        public UsbPortHidl mUsbPortHidl;
+
+        HALCallback(IndentingPrintWriter pw, UsbPortManager portManager, UsbPortHidl usbPortHidl) {
+            this.mPw = pw;
+            this.mPortManager = portManager;
+            this.mUsbPortHidl = usbPortHidl;
+        }
+
+        public void notifyPortStatusChange(
+                ArrayList<android.hardware.usb.V1_0.PortStatus> currentPortStatus, int retval) {
+            if (!mUsbPortHidl.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
+
+            for (android.hardware.usb.V1_0.PortStatus current : currentPortStatus) {
+                RawPortInfo temp = new RawPortInfo(current.portName,
+                        current.supportedModes, CONTAMINANT_PROTECTION_NONE,
+                        current.currentMode,
+                        current.canChangeMode, current.currentPowerRole,
+                        current.canChangePowerRole,
+                        current.currentDataRole, current.canChangeDataRole,
+                        false, CONTAMINANT_PROTECTION_NONE,
+                        false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataEnabled);
+                newPortInfo.add(temp);
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_0: "
+                        + current.portName);
+            }
+
+            mPortManager.updatePorts(newPortInfo);
+        }
+
+
+        public void notifyPortStatusChange_1_1(ArrayList<PortStatus_1_1> currentPortStatus,
+                int retval) {
+            if (!mUsbPortHidl.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
+
+            int numStatus = currentPortStatus.size();
+            for (int i = 0; i < numStatus; i++) {
+                PortStatus_1_1 current = currentPortStatus.get(i);
+                RawPortInfo temp = new RawPortInfo(current.status.portName,
+                        current.supportedModes, CONTAMINANT_PROTECTION_NONE,
+                        current.currentMode,
+                        current.status.canChangeMode, current.status.currentPowerRole,
+                        current.status.canChangePowerRole,
+                        current.status.currentDataRole, current.status.canChangeDataRole,
+                        false, CONTAMINANT_PROTECTION_NONE,
+                        false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataEnabled);
+                newPortInfo.add(temp);
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_1: "
+                        + current.status.portName);
+            }
+            mPortManager.updatePorts(newPortInfo);
+        }
+
+        public void notifyPortStatusChange_1_2(
+                ArrayList<PortStatus> currentPortStatus, int retval) {
+            if (!mUsbPortHidl.mSystemReady) {
+                return;
+            }
+
+            if (retval != Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<>();
+
+            int numStatus = currentPortStatus.size();
+            for (int i = 0; i < numStatus; i++) {
+                PortStatus current = currentPortStatus.get(i);
+                RawPortInfo temp = new RawPortInfo(current.status_1_1.status.portName,
+                        current.status_1_1.supportedModes,
+                        current.supportedContaminantProtectionModes,
+                        current.status_1_1.currentMode,
+                        current.status_1_1.status.canChangeMode,
+                        current.status_1_1.status.currentPowerRole,
+                        current.status_1_1.status.canChangePowerRole,
+                        current.status_1_1.status.currentDataRole,
+                        current.status_1_1.status.canChangeDataRole,
+                        current.supportsEnableContaminantPresenceProtection,
+                        current.contaminantProtectionStatus,
+                        current.supportsEnableContaminantPresenceDetection,
+                        current.contaminantDetectionStatus,
+                        sUsbDataEnabled);
+                newPortInfo.add(temp);
+                UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_2: "
+                        + current.status_1_1.status.portName);
+            }
+            mPortManager.updatePorts(newPortInfo);
+        }
+
+        public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
+            if (retval == Status.SUCCESS) {
+                UsbPortManager.logAndPrint(Log.INFO, mPw, portName + " role switch successful");
+            } else {
+                UsbPortManager.logAndPrint(Log.ERROR, mPw, portName + " role switch failed");
+            }
+        }
+    }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 6122b08..8a8cdb0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SuppressLint;
@@ -31,6 +32,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -70,6 +72,7 @@
  */
 @SuppressAutoDoc
 @SystemService(Context.TELECOM_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_TELECOM)
 public class TelecomManager {
 
     /**
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 9a991a1..dc878df 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -192,6 +192,7 @@
             case TelephonyManager.DATA_CONNECTED: return "CONNECTED";
             case TelephonyManager.DATA_SUSPENDED: return "SUSPENDED";
             case TelephonyManager.DATA_DISCONNECTING: return "DISCONNECTING";
+            case TelephonyManager.DATA_HANDOVER_IN_PROGRESS: return "HANDOVERINPROGRESS";
             case TelephonyManager.DATA_UNKNOWN: return "UNKNOWN";
         }
         // This is the error case. The well-defined value for UNKNOWN is -1.
diff --git a/telephony/java/Android.bp b/telephony/java/Android.bp
index 3941b30..76a420c 100644
--- a/telephony/java/Android.bp
+++ b/telephony/java/Android.bp
@@ -13,6 +13,15 @@
     srcs: [
         "**/*.java",
         "**/*.aidl",
+        ":statslog-telephony-java-gen",
     ],
     visibility: ["//frameworks/base"],
 }
+
+genrule {
+    name: "statslog-telephony-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module telephony" +
+        " --javaPackage com.android.internal.telephony --javaClass TelephonyStatsLog",
+    out: ["com/android/internal/telephony/TelephonyStatsLog.java"],
+}
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index ffdb23f..e7d95e4 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -16,6 +16,10 @@
 
 package android.telephony;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
+
+import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_ANOMALY_DETECTED;
+
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.content.Context;
@@ -24,6 +28,7 @@
 import android.content.pm.ResolveInfo;
 import android.os.ParcelUuid;
 
+import com.android.internal.telephony.TelephonyStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
 
@@ -70,6 +75,7 @@
      *
      * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is
      * system protected. Invoking this method unless you are the system will result in an error.
+     * Carrier Id will be set as UNKNOWN_CARRIER_ID.
      *
      * @param eventId a fixed event ID that will be sent for each instance of the same event. This
      *        ID should be generated randomly.
@@ -78,11 +84,34 @@
      *        static and must not contain any sensitive information (especially PII).
      */
     public static void reportAnomaly(@NonNull UUID eventId, String description) {
+        reportAnomaly(eventId, description, UNKNOWN_CARRIER_ID);
+    }
+
+    /**
+     * If enabled, build and send an intent to a Debug Service for logging.
+     *
+     * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is
+     * system protected. Invoking this method unless you are the system will result in an error.
+     *
+     * @param eventId a fixed event ID that will be sent for each instance of the same event. This
+     *        ID should be generated randomly.
+     * @param description an optional description, that if included will be used as the subject for
+     *        identification and discussion of this event. This description should ideally be
+     *        static and must not contain any sensitive information (especially PII).
+     * @param carrierId the carrier of the id associated with this event.
+     */
+    public static void reportAnomaly(@NonNull UUID eventId, String description, int carrierId) {
         if (sContext == null) {
             Rlog.w(TAG, "AnomalyReporter not yet initialized, dropping event=" + eventId);
             return;
         }
 
+        TelephonyStatsLog.write(
+                TELEPHONY_ANOMALY_DETECTED,
+                carrierId,
+                eventId.getLeastSignificantBits(),
+                eventId.getMostSignificantBits());
+
         // If this event has already occurred, skip sending intents for it; regardless log its
         // invocation here.
         Integer count = sEvents.containsKey(eventId) ? sEvents.get(eventId) + 1 : 1;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0d0142c..8956b46 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SuppressLint;
@@ -28,6 +29,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.net.NetworkCapabilities;
 import android.net.ipsec.ike.SaProposal;
 import android.os.Build;
@@ -55,6 +57,7 @@
  * Provides access to telephony configuration values that are carrier-specific.
  */
 @SystemService(Context.CARRIER_CONFIG_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
 public class CarrierConfigManager {
     private final static String TAG = "CarrierConfigManager";
 
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 3a3b363..ac1f376 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1661,8 +1661,8 @@
 
     /** @hide */
     public static String toString(@DataFailureCause int dataFailCause) {
-        int cause = getFailCause(dataFailCause);
-        return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause);
+        return sFailCauseMap.getOrDefault(dataFailCause, "UNKNOWN") + "(0x"
+                + Integer.toHexString(dataFailCause) + ")";
     }
 
     /** @hide */
@@ -1673,4 +1673,9 @@
             return UNKNOWN;
         }
     }
+
+    /** @hide */
+    public static boolean isFailCauseExisting(@DataFailureCause int failCause) {
+        return sFailCauseMap.containsKey(failCause);
+    }
 }
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
index 6b9871c..b0ff949 100644
--- a/telephony/java/android/telephony/ImsManager.java
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -17,11 +17,13 @@
 package android.telephony.ims;
 
 import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
 import android.annotation.SdkConstant;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.telephony.BinderCacheManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
@@ -33,6 +35,7 @@
  * Provides access to information about Telephony IMS services on the device.
  */
 @SystemService(Context.TELEPHONY_IMS_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public class ImsManager {
 
     /**
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 1a5a5ae..dcc1c0c 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -183,8 +183,17 @@
     @TransportType
     private final int mTransportType;
 
+    /**
+     * The initial registration state
+     */
     @RegistrationState
-    private final int mRegistrationState;
+    private final int mInitialRegistrationState;
+
+    /**
+     * The registration state that might have been overridden by config
+     */
+    @RegistrationState
+    private int mRegistrationState;
 
     /**
      * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type
@@ -255,6 +264,7 @@
         mDomain = domain;
         mTransportType = transportType;
         mRegistrationState = registrationState;
+        mInitialRegistrationState = registrationState;
         mRoamingType = (registrationState == REGISTRATION_STATE_ROAMING)
                 ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
         setAccessNetworkTechnology(accessNetworkTechnology);
@@ -310,6 +320,7 @@
         mDomain = source.readInt();
         mTransportType = source.readInt();
         mRegistrationState = source.readInt();
+        mInitialRegistrationState = source.readInt();
         mRoamingType = source.readInt();
         mAccessNetworkTechnology = source.readInt();
         mRejectCause = source.readInt();
@@ -336,6 +347,7 @@
         mDomain = nri.mDomain;
         mTransportType = nri.mTransportType;
         mRegistrationState = nri.mRegistrationState;
+        mInitialRegistrationState = nri.mInitialRegistrationState;
         mRoamingType = nri.mRoamingType;
         mAccessNetworkTechnology = nri.mAccessNetworkTechnology;
         mIsUsingCarrierAggregation = nri.mIsUsingCarrierAggregation;
@@ -398,6 +410,15 @@
     }
 
     /**
+     * @return The initial registration state.
+     *
+     * @hide
+     */
+    public @RegistrationState int getInitialRegistrationState() {
+        return mInitialRegistrationState;
+    }
+
+    /**
      * @return {@code true} if registered on roaming or home network, {@code false} otherwise.
      */
     public boolean isRegistered() {
@@ -451,6 +472,17 @@
      */
     public void setRoamingType(@ServiceState.RoamingType int roamingType) {
         mRoamingType = roamingType;
+
+        // make sure mRegistrationState to be consistent in case of any roaming type override
+        if (isRoaming()) {
+            if (mRegistrationState == REGISTRATION_STATE_HOME) {
+                mRegistrationState = REGISTRATION_STATE_ROAMING;
+            }
+        } else {
+            if (mRegistrationState == REGISTRATION_STATE_ROAMING) {
+                mRegistrationState = REGISTRATION_STATE_HOME;
+            }
+        }
     }
 
     /**
@@ -634,6 +666,8 @@
                 .append(" transportType=").append(
                         AccessNetworkConstants.transportTypeToString(mTransportType))
                 .append(" registrationState=").append(registrationStateToString(mRegistrationState))
+                .append(" mInitialRegistrationState=")
+                .append(registrationStateToString(mInitialRegistrationState))
                 .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType))
                 .append(" accessNetworkTechnology=")
                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
@@ -654,10 +688,10 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
-                mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn,
-                mIsUsingCarrierAggregation);
+        return Objects.hash(mDomain, mTransportType, mRegistrationState, mInitialRegistrationState,
+                mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly,
+                mAvailableServices, mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState,
+                mRplmn, mIsUsingCarrierAggregation);
     }
 
     @Override
@@ -672,6 +706,7 @@
         return mDomain == other.mDomain
                 && mTransportType == other.mTransportType
                 && mRegistrationState == other.mRegistrationState
+                && mInitialRegistrationState == other.mInitialRegistrationState
                 && mRoamingType == other.mRoamingType
                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
                 && mRejectCause == other.mRejectCause
@@ -694,6 +729,7 @@
         dest.writeInt(mDomain);
         dest.writeInt(mTransportType);
         dest.writeInt(mRegistrationState);
+        dest.writeInt(mInitialRegistrationState);
         dest.writeInt(mRoamingType);
         dest.writeInt(mAccessNetworkTechnology);
         dest.writeInt(mRejectCause);
@@ -790,7 +826,7 @@
         private int mTransportType;
 
         @RegistrationState
-        private int mRegistrationState;
+        private int mInitialRegistrationState;
 
         @NetworkType
         private int mAccessNetworkTechnology;
@@ -851,7 +887,7 @@
          * @return The same instance of the builder.
          */
         public @NonNull Builder setRegistrationState(@RegistrationState int registrationState) {
-            mRegistrationState = registrationState;
+            mInitialRegistrationState = registrationState;
             return this;
         }
 
@@ -970,7 +1006,7 @@
          */
         @SystemApi
         public @NonNull NetworkRegistrationInfo build() {
-            return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
+            return new NetworkRegistrationInfo(mDomain, mTransportType, mInitialRegistrationState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
                     mCellIdentity, mRplmn, mVoiceSpecificRegistrationInfo,
                     mDataSpecificRegistrationInfo);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index d91134e..d978f57 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -23,16 +23,12 @@
 import android.os.Parcelable;
 import android.telephony.Annotation.NetworkType;
 
-import com.android.telephony.Rlog;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.Objects;
 
 public final class PhysicalChannelConfig implements Parcelable {
-    static final String TAG = "PhysicalChannelConfig";
-
     // TODO(b/72993578) consolidate these enums in a central location.
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -571,21 +567,19 @@
 
         public @NonNull Builder setNetworkType(@NetworkType int networkType) {
             if (!TelephonyManager.isNetworkTypeValid(networkType)) {
-                Rlog.e(TAG, "Builder.setNetworkType: Network type " + networkType + " is invalid.");
-            } else {
-                mNetworkType = networkType;
+                throw new IllegalArgumentException("Network type " + networkType + " is invalid.");
             }
+            mNetworkType = networkType;
             return this;
         }
 
         public @NonNull Builder setFrequencyRange(int frequencyRange) {
             if (!ServiceState.isFrequencyRangeValid(frequencyRange)
                     && frequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
-                Rlog.e(TAG, "Builder.setFrequencyRange: Frequency range " + frequencyRange
+                throw new IllegalArgumentException("Frequency range " + frequencyRange
                         + " is invalid.");
-            } else {
-                mFrequencyRange = frequencyRange;
             }
+            mFrequencyRange = frequencyRange;
             return this;
         }
 
@@ -601,21 +595,19 @@
 
         public @NonNull Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) {
             if (cellBandwidthDownlinkKhz < CELL_BANDWIDTH_UNKNOWN) {
-                Rlog.e(TAG, "Builder.setCellBandwidthDownlinkKhz: Cell downlink bandwidth(kHz) "
+                throw new IllegalArgumentException("Cell downlink bandwidth(kHz) "
                         + cellBandwidthDownlinkKhz + " is invalid.");
-            } else {
-                mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
             }
+            mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
             return this;
         }
 
         public @NonNull Builder setCellBandwidthUplinkKhz(int cellBandwidthUplinkKhz) {
             if (cellBandwidthUplinkKhz < CELL_BANDWIDTH_UNKNOWN) {
-                Rlog.e(TAG, "Builder.setCellBandwidthUplinkKhz: Cell uplink bandwidth(kHz) "
+                throw new IllegalArgumentException("Cell uplink bandwidth(kHz) "
                         + cellBandwidthUplinkKhz + " is invalid.");
-            } else {
-                mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz;
             }
+            mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz;
             return this;
         }
 
@@ -632,20 +624,18 @@
 
         public @NonNull Builder setPhysicalCellId(int physicalCellId) {
             if (physicalCellId > PHYSICAL_CELL_ID_MAXIMUM_VALUE) {
-                Rlog.e(TAG, "Builder.setPhysicalCellId: Physical cell ID " + physicalCellId
+                throw new IllegalArgumentException("Physical cell ID " + physicalCellId
                         + " is over limit.");
-            } else {
-                mPhysicalCellId = physicalCellId;
             }
+            mPhysicalCellId = physicalCellId;
             return this;
         }
 
         public @NonNull Builder setBand(int band) {
             if (band <= BAND_UNKNOWN) {
-                Rlog.e(TAG, "Builder.setBand: Band " + band + " is invalid.");
-            } else {
-                mBand = band;
+                throw new IllegalArgumentException("Band " + band + " is invalid.");
             }
+            mBand = band;
             return this;
         }
     }
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 5171cf9..7df06b0 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -22,6 +22,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
@@ -32,6 +33,7 @@
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.CursorWindow;
 import android.net.Uri;
 import android.os.Build;
@@ -75,6 +77,7 @@
  *
  * @see SubscriptionManager#getActiveSubscriptionInfoList()
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
 public final class SmsManager {
     private static final String TAG = "SmsManager";
 
@@ -2633,6 +2636,19 @@
      *  sending the message.
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
+     * The result code will be <code>Activity.RESULT_OK</code> for success
+     * or one of these errors:<br>
+     * <code>MMS_ERROR_UNSPECIFIED</code><br>
+     * <code>MMS_ERROR_INVALID_APN</code><br>
+     * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
+     * <code>MMS_ERROR_HTTP_FAILURE</code><br>
+     * <code>MMS_ERROR_IO_ERROR</code><br>
+     * <code>MMS_ERROR_RETRY</code><br>
+     * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
+     * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
+     * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
+     * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
+     * <code>MMS_ERROR_DATA_DISABLED</code><br>
      * @throws IllegalArgumentException if contentUri is empty
      */
     public void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
@@ -2661,6 +2677,19 @@
      *  sending the message.
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is successfully sent, or failed
+     * The result code will be <code>Activity.RESULT_OK</code> for success
+     * or one of these errors:<br>
+     * <code>MMS_ERROR_UNSPECIFIED</code><br>
+     * <code>MMS_ERROR_INVALID_APN</code><br>
+     * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
+     * <code>MMS_ERROR_HTTP_FAILURE</code><br>
+     * <code>MMS_ERROR_IO_ERROR</code><br>
+     * <code>MMS_ERROR_RETRY</code><br>
+     * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
+     * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
+     * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
+     * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
+     * <code>MMS_ERROR_DATA_DISABLED</code><br>
      * @param messageId an id that uniquely identifies the message requested to be sent.
      * Used for logging and diagnostics purposes. The id may be 0.
      * @throws IllegalArgumentException if contentUri is empty
@@ -2707,6 +2736,19 @@
      *  downloading the message.
      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is downloaded, or the download is failed
+     * The result code will be <code>Activity.RESULT_OK</code> for success
+     * or one of these errors:<br>
+     * <code>MMS_ERROR_UNSPECIFIED</code><br>
+     * <code>MMS_ERROR_INVALID_APN</code><br>
+     * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
+     * <code>MMS_ERROR_HTTP_FAILURE</code><br>
+     * <code>MMS_ERROR_IO_ERROR</code><br>
+     * <code>MMS_ERROR_RETRY</code><br>
+     * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
+     * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
+     * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
+     * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
+     * <code>MMS_ERROR_DATA_DISABLED</code><br>
      * @throws IllegalArgumentException if locationUrl or contentUri is empty
      */
     public void downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri,
@@ -2737,6 +2779,19 @@
      *  downloading the message.
      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
      *  broadcast when the message is downloaded, or the download is failed
+     * The result code will be <code>Activity.RESULT_OK</code> for success
+     * or one of these errors:<br>
+     * <code>MMS_ERROR_UNSPECIFIED</code><br>
+     * <code>MMS_ERROR_INVALID_APN</code><br>
+     * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
+     * <code>MMS_ERROR_HTTP_FAILURE</code><br>
+     * <code>MMS_ERROR_IO_ERROR</code><br>
+     * <code>MMS_ERROR_RETRY</code><br>
+     * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
+     * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
+     * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
+     * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
+     * <code>MMS_ERROR_DATA_DISABLED</code><br>
      * @param messageId an id that uniquely identifies the message requested to be downloaded.
      * Used for logging and diagnostics purposes. The id may be 0.
      * @throws IllegalArgumentException if locationUrl or contentUri is empty
@@ -2768,15 +2823,62 @@
     }
 
     // MMS send/download failure result codes
+
+    /**
+     * Unspecific MMS error occurred during send/download.
+     */
     public static final int MMS_ERROR_UNSPECIFIED = 1;
+
+    /**
+     * ApnException occurred during MMS network setup.
+     */
     public static final int MMS_ERROR_INVALID_APN = 2;
+
+    /**
+     * An error occurred during the MMS connection setup.
+     */
     public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3;
+
+    /**
+     * An error occurred during the HTTP client setup.
+     */
     public static final int MMS_ERROR_HTTP_FAILURE = 4;
+
+    /**
+     * An I/O error occurred reading the PDU.
+     */
     public static final int MMS_ERROR_IO_ERROR = 5;
+
+    /**
+     * An error occurred while retrying sending/downloading the MMS.
+     */
     public static final int MMS_ERROR_RETRY = 6;
+
+    /**
+     * The carrier-dependent configuration values could not be loaded.
+     */
     public static final int MMS_ERROR_CONFIGURATION_ERROR = 7;
+
+    /**
+     * There is no data network.
+     */
     public static final int MMS_ERROR_NO_DATA_NETWORK = 8;
 
+    /**
+     * The subscription id for the send/download is invalid.
+     */
+    public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9;
+
+    /**
+     * The subscription id for the send/download is inactive.
+     */
+    public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10;
+
+    /**
+     * Data is disabled for the MMS APN.
+     */
+    public static final int MMS_ERROR_DATA_DISABLED = 11;
+
     /** Intent extra name for MMS sending result data in byte array type */
     public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
     /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 974392e..d2858ec 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -26,6 +26,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -92,6 +93,7 @@
  * and provides information about the current Telephony Subscriptions.
  */
 @SystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
 public class SubscriptionManager {
     private static final String LOG_TAG = "SubscriptionManager";
     private static final boolean DBG = false;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b482515..bbd3c46 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -49,6 +49,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.ConnectivityManager;
 import android.net.Uri;
@@ -174,6 +175,7 @@
  * that do not implement this feature, the behavior is not reliable.
  */
 @SystemService(Context.TELEPHONY_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY)
 public class TelephonyManager {
     private static final String TAG = "TelephonyManager";
 
@@ -2055,6 +2057,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     public String getImei() {
         return getImei(getSlotIndex());
     }
@@ -2096,6 +2099,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     public String getImei(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -2113,6 +2117,7 @@
      * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
      * available.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     @Nullable
     public String getTypeAllocationCode() {
         return getTypeAllocationCode(getSlotIndex());
@@ -2124,6 +2129,7 @@
      *
      * @param slotIndex of which Type Allocation Code is returned
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_GSM)
     @Nullable
     public String getTypeAllocationCode(int slotIndex) {
         ITelephony telephony = getITelephony();
@@ -2170,6 +2176,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getMeid() {
         return getMeid(getSlotIndex());
     }
@@ -2208,6 +2215,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getMeid(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -2231,6 +2239,7 @@
      * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
      * available.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     @Nullable
     public String getManufacturerCode() {
         return getManufacturerCode(getSlotIndex());
@@ -2242,6 +2251,7 @@
      *
      * @param slotIndex of which Type Allocation Code is returned
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     @Nullable
     public String getManufacturerCode(int slotIndex) {
         ITelephony telephony = getITelephony();
@@ -2287,6 +2297,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getNai() {
         return getNaiBySubscriberId(getSubId());
     }
@@ -2620,6 +2631,7 @@
      * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
      * on a CDMA network).
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public String getNetworkOperatorName() {
         return getNetworkOperatorName(getSubId());
     }
@@ -2647,6 +2659,7 @@
      * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
      * on a CDMA network).
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public String getNetworkOperator() {
         return getNetworkOperatorForPhone(getPhoneId());
     }
@@ -2695,6 +2708,7 @@
      * @see #createForSubscriptionId(int)
      * @see #createForPhoneAccountHandle(PhoneAccountHandle)
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public String getNetworkSpecifier() {
         return String.valueOf(getSubId());
     }
@@ -2717,6 +2731,7 @@
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @WorkerThread
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public PersistableBundle getCarrierConfig() {
         CarrierConfigManager carrierConfigManager = mContext
                 .getSystemService(CarrierConfigManager.class);
@@ -2729,6 +2744,7 @@
      * <p>
      * Availability: Only when user registered to a network.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isNetworkRoaming() {
         return isNetworkRoaming(getSubId());
     }
@@ -2758,6 +2774,7 @@
      * @return the lowercase 2 character ISO-3166-1 alpha-2 country code, or empty string if not
      * available.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public String getNetworkCountryIso() {
         return getNetworkCountryIso(getSlotIndex());
     }
@@ -2780,6 +2797,7 @@
      * @throws IllegalArgumentException when the slotIndex is invalid.
      *
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     @NonNull
     public String getNetworkCountryIso(int slotIndex) {
         try {
@@ -2997,6 +3015,7 @@
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public @NetworkType int getDataNetworkType() {
         return getDataNetworkType(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
     }
@@ -3042,6 +3061,7 @@
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public @NetworkType int getVoiceNetworkType() {
         return getVoiceNetworkType(getSubId());
     }
@@ -3134,8 +3154,10 @@
                 return "LTE_CA";
             case NETWORK_TYPE_NR:
                 return "NR";
-            default:
+            case NETWORK_TYPE_UNKNOWN:
                 return "UNKNOWN";
+            default:
+                return "UNKNOWN(" + type + ")";
         }
     }
 
@@ -3379,6 +3401,7 @@
     /**
      * @return true if a ICC card is present
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean hasIccCard() {
         return hasIccCard(getSlotIndex());
     }
@@ -3421,6 +3444,7 @@
      * @see #SIM_STATE_CARD_IO_ERROR
      * @see #SIM_STATE_CARD_RESTRICTED
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimState() {
         int simState = getSimStateIncludingLoaded();
         if (simState == SIM_STATE_LOADED) {
@@ -3463,6 +3487,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimCardState() {
         int simState = getSimState();
         return getSimCardStateFromSimState(simState);
@@ -3508,6 +3533,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimCardState(int physicalSlotIndex, int portIndex) {
         int simState = getSimState(getLogicalSlotIndex(physicalSlotIndex, portIndex));
         return getSimCardStateFromSimState(simState);
@@ -3564,6 +3590,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimApplicationState() {
         int simState = getSimStateIncludingLoaded();
         return getSimApplicationStateFromSimState(simState);
@@ -3616,6 +3643,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimApplicationState(int physicalSlotIndex, int portIndex) {
         int simState =
                 SubscriptionManager.getSimStateForSlotIndex(getLogicalSlotIndex(physicalSlotIndex,
@@ -3657,6 +3685,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean isApplicationOnUicc(@UiccAppType int appType) {
         try {
             ITelephony service = getITelephony();
@@ -3685,6 +3714,7 @@
      * @see #SIM_STATE_CARD_IO_ERROR
      * @see #SIM_STATE_CARD_RESTRICTED
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @SimState int getSimState(int slotIndex) {
         int simState = SubscriptionManager.getSimStateForSlotIndex(slotIndex);
         if (simState == SIM_STATE_LOADED) {
@@ -3701,6 +3731,7 @@
      *
      * @see #getSimState
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getSimOperator() {
         return getSimOperatorNumeric();
     }
@@ -3785,6 +3816,7 @@
      *
      * @see #getSimState
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getSimOperatorName() {
         return getSimOperatorNameForPhone(getPhoneId());
     }
@@ -3822,6 +3854,7 @@
      * @return the lowercase 2 character ISO-3166-1 alpha-2 country code, or empty string is not
      * available.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getSimCountryIso() {
         return getSimCountryIsoForPhone(getPhoneId());
     }
@@ -3880,6 +3913,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getSimSerialNumber() {
          return getSimSerialNumber(getSubId());
     }
@@ -3947,6 +3981,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isLteCdmaEvdoGsmWcdmaEnabled() {
         return getLteOnCdmaMode(getSubId()) == PhoneConstants.LTE_ON_CDMA_TRUE;
     }
@@ -3990,6 +4025,7 @@
      *
      * @return card ID of the default eUICC card, if loaded.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
     public int getCardIdForDefaultEuicc() {
         try {
             ITelephony telephony = getITelephony();
@@ -4023,6 +4059,7 @@
      * the caller does not have adequate permissions for that card.
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @NonNull
     public List<UiccCardInfo> getUiccCardsInfo() {
         try {
@@ -4048,6 +4085,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public UiccSlotInfo[] getUiccSlotsInfo() {
         try {
             ITelephony telephony = getITelephony();
@@ -4190,6 +4228,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void setSimSlotMapping(@NonNull Collection<UiccSlotMapping> slotMapping) {
         try {
             ITelephony telephony = getITelephony();
@@ -4253,6 +4292,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @NonNull
     public Collection<UiccSlotMapping> getSimSlotMapping() {
         List<UiccSlotMapping> slotMap = new ArrayList<>();
@@ -4308,6 +4348,7 @@
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getSubscriberId() {
         return getSubscriberId(getSubId());
     }
@@ -4359,6 +4400,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     @Nullable
     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(@KeyType int keyType) {
@@ -4403,6 +4445,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     public void resetCarrierKeysForImsiEncryption() {
         try {
@@ -4602,6 +4645,7 @@
      * @param callback A callback called when the upload operation terminates, either in success
      *                 or in error.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void uploadCallComposerPicture(@NonNull Path pictureToUpload,
             @NonNull String contentType,
             @CallbackExecutor @NonNull Executor executor,
@@ -4708,6 +4752,7 @@
      * @param callback A callback called when the upload operation terminates, either in success
      *                 or in error.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void uploadCallComposerPicture(@NonNull InputStream pictureToUpload,
             @NonNull String contentType,
             @CallbackExecutor @NonNull Executor executor,
@@ -4843,6 +4888,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getGroupIdLevel1() {
         try {
             IPhoneSubInfo info = getSubscriberInfoService();
@@ -5098,6 +5144,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @NonNull String[] getMergedImsisFromGroup() {
         try {
             ITelephony telephony = getITelephony();
@@ -5177,6 +5224,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public String getVoiceMailNumber() {
         return getVoiceMailNumber(getSubId());
     }
@@ -5212,6 +5260,7 @@
      * @param alphaTag The alpha tag to display.
      * @param number The voicemail number.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean setVoiceMailNumber(String alphaTag, String number) {
         return setVoiceMailNumber(getSubId(), alphaTag, number);
     }
@@ -5251,6 +5300,7 @@
      * be implemented instead.
      */
     @SystemApi
+    @Deprecated
     @SuppressLint("RequiresPermission")
     public void setVisualVoicemailEnabled(PhoneAccountHandle phoneAccountHandle, boolean enabled){
     }
@@ -5265,6 +5315,7 @@
      * be implemented instead.
      */
     @SystemApi
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @SuppressLint("RequiresPermission")
     public boolean isVisualVoicemailEnabled(PhoneAccountHandle phoneAccountHandle){
@@ -5286,6 +5337,7 @@
      */
     @SystemApi
     @SuppressLint("RequiresPermission")
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @Nullable
     public Bundle getVisualVoicemailSettings(){
         try {
@@ -5315,6 +5367,7 @@
     @Nullable
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public String getVisualVoicemailPackageName() {
         try {
             ITelephony telephony = getITelephony();
@@ -5341,6 +5394,7 @@
      * @see TelecomManager#getDefaultDialerPackage()
      * @see CarrierConfigManager#KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings settings) {
         if (settings == null) {
             disableVisualVoicemailSmsFilter(mSubId);
@@ -5370,6 +5424,7 @@
      * @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
      * @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void sendVisualVoicemailSms(String number, int port, String text,
             PendingIntent sentIntent) {
         sendVisualVoicemailSmsForSubscriber(mSubId, number, port, text, sentIntent);
@@ -5557,6 +5612,7 @@
       */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void setVoiceActivationState(@SimActivationState int activationState) {
         setVoiceActivationState(getSubId(), activationState);
     }
@@ -5604,6 +5660,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public void setDataActivationState(@SimActivationState int activationState) {
         setDataActivationState(getSubId(), activationState);
     }
@@ -5651,6 +5708,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public @SimActivationState int getVoiceActivationState() {
         return getVoiceActivationState(getSubId());
     }
@@ -5700,6 +5758,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public @SimActivationState int getDataActivationState() {
         return getDataActivationState(getSubId());
     }
@@ -5776,6 +5835,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public String getVoiceMailAlphaTag() {
         return getVoiceMailAlphaTag(getSubId());
     }
@@ -5858,6 +5918,7 @@
     @Nullable
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getIsimDomain() {
         try {
             IPhoneSubInfo info = getSubscriberInfoService();
@@ -5958,6 +6019,7 @@
      * @return The call state of the subscription associated with this TelephonyManager instance.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public @CallState int getCallStateForSubscription() {
         return getCallState(getSubId());
     }
@@ -6056,6 +6118,7 @@
      * @see #DATA_ACTIVITY_INOUT
      * @see #DATA_ACTIVITY_DORMANT
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public int getDataActivity() {
         try {
             ITelephony telephony = getITelephony();
@@ -6128,6 +6191,7 @@
      * @see #DATA_DISCONNECTING
      * @see #DATA_HANDOVER_IN_PROGRESS
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public int getDataState() {
         try {
             ITelephony telephony = getITelephony();
@@ -6404,6 +6468,7 @@
      * on any device with a telephony radio, even if the device is
      * data-only.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean isVoiceCapable() {
         if (mContext == null) return true;
         return mContext.getResources().getBoolean(
@@ -6419,6 +6484,7 @@
      * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
      *       disabled when device doesn't support sms.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public boolean isSmsCapable() {
         if (mContext == null) return true;
         return mContext.getResources().getBoolean(
@@ -6468,6 +6534,7 @@
      * information is unavailable.
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public List<CellInfo> getAllCellInfo() {
         try {
             ITelephony telephony = getITelephony();
@@ -6562,6 +6629,7 @@
      * @param callback a callback to receive CellInfo.
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void requestCellInfoUpdate(
             @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
         try {
@@ -6625,6 +6693,7 @@
     @SystemApi
     @RequiresPermission(allOf = {android.Manifest.permission.ACCESS_FINE_LOCATION,
             android.Manifest.permission.MODIFY_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void requestCellInfoUpdate(@NonNull WorkSource workSource,
             @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
         try {
@@ -6706,6 +6775,7 @@
     /**
      * Returns the MMS user agent.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public String getMmsUserAgent() {
         try {
             ITelephony telephony = getITelephony();
@@ -6721,6 +6791,7 @@
     /**
      * Returns the MMS user agent profile URL.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public String getMmsUAProfUrl() {
         try {
             ITelephony telephony = getITelephony();
@@ -6782,6 +6853,7 @@
      * @deprecated instead use {@link #iccOpenLogicalChannelByPort(int, int, String, int)}
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     @Nullable
     @Deprecated
@@ -6881,6 +6953,7 @@
      * @param p2 P2 parameter (described in ISO 7816-4).
      * @return an IccOpenLogicalChannelResponse object.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID, int p2) {
         return iccOpenLogicalChannel(getSubId(), AID, p2);
     }
@@ -6949,6 +7022,7 @@
      * @deprecated instead use {@link #iccCloseLogicalChannelByPort(int, int, int)}
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     @Deprecated
     public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
@@ -7018,6 +7092,7 @@
      *            iccOpenLogicalChannel.
      * @return true if the channel was closed successfully.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean iccCloseLogicalChannel(int channel) {
         return iccCloseLogicalChannel(getSubId(), channel);
     }
@@ -7080,6 +7155,7 @@
      * {@link #iccTransmitApduLogicalChannelByPort(int, int, int, int, int, int, int, int, String)}
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     @Nullable
     @Deprecated
@@ -7162,6 +7238,7 @@
      * @return The APDU response from the ICC card with the status appended at
      *            the end.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String iccTransmitApduLogicalChannel(int channel, int cla,
             int instruction, int p1, int p2, int p3, String data) {
         return iccTransmitApduLogicalChannel(getSubId(), channel, cla,
@@ -7230,6 +7307,7 @@
      * {@link #iccTransmitApduBasicChannelByPort(int, int, int, int, int, int, int, String)}
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     @NonNull
     @Deprecated
@@ -7307,6 +7385,7 @@
      * @return The APDU response from the ICC card with the status appended at
      *            the end.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String iccTransmitApduBasicChannel(int cla,
             int instruction, int p1, int p2, int p3, String data) {
         return iccTransmitApduBasicChannel(getSubId(), cla,
@@ -7362,6 +7441,7 @@
      * @param filePath
      * @return The APDU response.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
             String filePath) {
         return iccExchangeSimIO(getSubId(), fileID, command, p1, p2, p3, filePath);
@@ -7410,6 +7490,7 @@
      *         with the last 4 bytes being the status word. If the command fails,
      *         returns an empty string.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String sendEnvelopeWithStatus(String content) {
         return sendEnvelopeWithStatus(getSubId(), content);
     }
@@ -7573,6 +7654,7 @@
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean resetRadioConfig() {
         try {
             ITelephony telephony = getITelephony();
@@ -7600,6 +7682,7 @@
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean rebootRadio() {
         try {
             ITelephony telephony = getITelephony();
@@ -7621,6 +7704,7 @@
      * subscription ID is returned. Otherwise, the default subscription ID will be returned.
      *
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int getSubscriptionId() {
         return getSubId();
     }
@@ -7731,6 +7815,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void requestNumberVerification(@NonNull PhoneNumberRange range, long timeoutMillis,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull NumberVerificationCallback callback) {
@@ -7944,6 +8029,7 @@
     @Nullable
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getIsimIst() {
         try {
             IPhoneSubInfo info = getSubscriberInfoService();
@@ -8028,6 +8114,7 @@
     // TODO(b/73660190): This should probably require MODIFY_PHONE_STATE, not
     // READ_PRIVILEGED_PHONE_STATE. It certainly shouldn't reference the permission in Javadoc since
     // it's not public API.
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getIccAuthentication(int appType, int authType, String data) {
         return getIccAuthentication(getSubId(), appType, authType, data);
     }
@@ -8081,6 +8168,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String[] getForbiddenPlmns() {
       return getForbiddenPlmns(getSubId(), APPTYPE_USIM);
     }
@@ -8130,6 +8218,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int setForbiddenPlmns(@NonNull List<String> fplmns) {
         try {
             ITelephony telephony = getITelephony();
@@ -8146,24 +8235,6 @@
     }
 
     /**
-     * Get P-CSCF address from PCO after data connection is established or modified.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
-     * @return array of P-CSCF address
-     * @hide
-     */
-    public String[] getPcscfAddress(String apnType) {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony == null)
-                return new String[0];
-            return telephony.getPcscfAddress(apnType, getOpPackageName(), getAttributionTag());
-        } catch (RemoteException e) {
-            return new String[0];
-        }
-    }
-
-
-    /**
      * Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
      * Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
      * recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
@@ -8174,6 +8245,7 @@
     @SystemApi
     @WorkerThread
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
     public void resetIms(int slotIndex) {
         try {
             ITelephony telephony = getITelephony();
@@ -8608,6 +8680,7 @@
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @NetworkTypeBitMask long getAllowedNetworkTypesBitmask() {
         try {
             ITelephony telephony = getITelephony();
@@ -8659,6 +8732,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void setNetworkSelectionModeAutomatic() {
         try {
             ITelephony telephony = getITelephony();
@@ -8747,6 +8821,7 @@
             android.Manifest.permission.MODIFY_PHONE_STATE,
             Manifest.permission.ACCESS_FINE_LOCATION
     })
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public NetworkScan requestNetworkScan(
             NetworkScanRequest request, Executor executor,
             TelephonyScanManager.NetworkScanCallback callback) {
@@ -8839,6 +8914,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setNetworkSelectionModeManual(String operatorNumeric, boolean persistSelection) {
         return setNetworkSelectionModeManual(
                 new OperatorInfo(
@@ -8868,6 +8944,7 @@
      * @return {@code true} on success; {@code false} on any failure.
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setNetworkSelectionModeManual(@NonNull String operatorNumeric,
             boolean persistSelection, @AccessNetworkConstants.RadioAccessNetworkType int ran) {
         return setNetworkSelectionModeManual(new OperatorInfo("" /* operatorAlphaLong */,
@@ -8923,6 +9000,7 @@
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_PRECISE_PHONE_STATE
     })
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @NetworkSelectionMode int getNetworkSelectionMode() {
         int mode = NETWORK_SELECTION_MODE_UNKNOWN;
         try {
@@ -8948,6 +9026,7 @@
      */
     @SuppressAutoDoc // No support carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @NonNull String getManualNetworkSelectionPlmn() {
         try {
             ITelephony telephony = getITelephony();
@@ -8977,6 +9056,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public boolean isInEmergencySmsMode() {
         try {
             ITelephony telephony = getITelephony();
@@ -9051,6 +9131,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
+                networkTypeBitmask = checkNetworkTypeBitmask(networkTypeBitmask);
                 return telephony.setAllowedNetworkTypesForReason(getSubId(),
                         TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, networkTypeBitmask);
             }
@@ -9061,6 +9142,20 @@
     }
 
     /**
+     * If {@link #NETWORK_TYPE_BITMASK_LTE_CA} bit is set, convert it to NETWORK_TYPE_BITMASK_LTE.
+     *
+     * @param networkTypeBitmask The networkTypeBitmask being checked
+     * @return The checked/converted networkTypeBitmask
+     */
+    private long checkNetworkTypeBitmask(@NetworkTypeBitMask long networkTypeBitmask) {
+        if ((networkTypeBitmask & NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
+            networkTypeBitmask ^= NETWORK_TYPE_BITMASK_LTE_CA;
+            networkTypeBitmask |= NETWORK_TYPE_BITMASK_LTE;
+        }
+        return networkTypeBitmask;
+    }
+
+    /**
      * Set the allowed network types of the device. This is for carrier or privileged apps to
      * enable/disable certain network types on the device. The user preferred network types should
      * be set through {@link #setPreferredNetworkTypeBitmask}.
@@ -9086,6 +9181,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
+                allowedNetworkTypes = checkNetworkTypeBitmask(allowedNetworkTypes);
                 return telephony.setAllowedNetworkTypesForReason(getSubId(),
                         TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER, allowedNetworkTypes);
             }
@@ -9171,6 +9267,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
+                allowedNetworkTypes = checkNetworkTypeBitmask(allowedNetworkTypes);
                 telephony.setAllowedNetworkTypesForReason(getSubId(), reason,
                         allowedNetworkTypes);
             } else {
@@ -9270,6 +9367,7 @@
      *
      * @return true on success; false on any failure.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setPreferredNetworkTypeToGlobal() {
         return setPreferredNetworkTypeToGlobal(getSubId());
     }
@@ -9297,6 +9395,7 @@
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isTetheringApnRequired() {
         return isTetheringApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
     }
@@ -9346,6 +9445,7 @@
      *
      * @return true if the app has carrier privileges.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean hasCarrierPrivileges() {
         return hasCarrierPrivileges(getSubId());
     }
@@ -9392,6 +9492,7 @@
      * @param brand The brand name to display/set.
      * @return true if the operation was executed correctly.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean setOperatorBrandOverride(String brand) {
         return setOperatorBrandOverride(getSubId(), brand);
     }
@@ -9494,6 +9595,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMdn() {
         return getCdmaMdn(getSubId());
     }
@@ -9501,6 +9603,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMdn(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -9517,6 +9620,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMin() {
         return getCdmaMin(getSubId());
     }
@@ -9524,6 +9628,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaMin(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -9540,6 +9645,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int checkCarrierPrivilegesForPackage(String pkgName) {
         try {
             ITelephony telephony = getITelephony();
@@ -9556,6 +9662,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
         try {
             ITelephony telephony = getITelephony();
@@ -9571,6 +9678,7 @@
 
     /** @hide */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public List<String> getCarrierPackageNamesForIntent(Intent intent) {
         return getCarrierPackageNamesForIntentAndPhone(intent, getPhoneId());
     }
@@ -9578,6 +9686,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
         try {
             ITelephony telephony = getITelephony();
@@ -9659,6 +9768,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @NonNull
     public List<String> getCarrierPrivilegedPackagesForAllActiveSubscriptions() {
         try {
@@ -9705,6 +9815,7 @@
      * @throws SecurityException if the caller does not have the permission.
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void setCallComposerStatus(@CallComposerStatus int status) {
         if (status > CALL_COMPOSER_STATUS_ON
                 || status < CALL_COMPOSER_STATUS_OFF) {
@@ -9733,6 +9844,7 @@
      * {@link #CALL_COMPOSER_STATUS_ON} or {@link #CALL_COMPOSER_STATUS_OFF}.
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public @CallComposerStatus int getCallComposerStatus() {
         try {
             ITelephony telephony = getITelephony();
@@ -9749,6 +9861,7 @@
     /** @hide */
     @SystemApi
     @SuppressLint("RequiresPermission")
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void dial(String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -9881,6 +9994,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean supplyPin(String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -9895,6 +10009,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean supplyPuk(String puk, String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -9960,6 +10075,7 @@
     @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public PinResult supplyIccLockPin(@NonNull String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -9995,6 +10111,7 @@
     @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public PinResult supplyIccLockPuk(@NonNull String puk, @NonNull String pin) {
         try {
             ITelephony telephony = getITelephony();
@@ -10064,6 +10181,7 @@
      * @param handler the {@link Handler} to run the request on.
      */
     @RequiresPermission(android.Manifest.permission.CALL_PHONE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void sendUssdRequest(String ussdRequest,
                                 final UssdResponseCallback callback, Handler handler) {
         checkNotNull(callback, "UssdResponseCallback cannot be null.");
@@ -10106,6 +10224,7 @@
      *
      * @return {@code true} if simultaneous voice and data supported, and {@code false} otherwise.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isConcurrentVoiceAndDataSupported() {
         try {
             ITelephony telephony = getITelephony();
@@ -10148,6 +10267,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void toggleRadioOnOff() {
         try {
             ITelephony telephony = getITelephony();
@@ -10161,6 +10281,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setRadio(boolean turnOn) {
         try {
             ITelephony telephony = getITelephony();
@@ -10175,6 +10296,7 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setRadioPower(boolean turnOn) {
         try {
             ITelephony telephony = getITelephony();
@@ -10196,6 +10318,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void shutdownAllRadios() {
         try {
             ITelephony telephony = getITelephony();
@@ -10216,6 +10339,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isAnyRadioPoweredOn() {
         try {
             ITelephony telephony = getITelephony();
@@ -10262,6 +10386,7 @@
     @SystemApi
     @RequiresPermission(anyOf = {android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @RadioPowerState int getRadioPowerState() {
         try {
             ITelephony telephony = getITelephony();
@@ -10288,11 +10413,12 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean enableDataConnectivity() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.enableDataConnectivity();
+                return telephony.enableDataConnectivity(getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
         }
@@ -10302,11 +10428,12 @@
     /** @hide */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean disableDataConnectivity() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.disableDataConnectivity();
+                return telephony.disableDataConnectivity(getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
         }
@@ -10315,6 +10442,7 @@
 
     /** @hide */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataConnectivityPossible() {
         try {
             ITelephony telephony = getITelephony();
@@ -10329,6 +10457,7 @@
 
     /** @hide */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean needsOtaServiceProvisioning() {
         try {
             ITelephony telephony = getITelephony();
@@ -10436,6 +10565,7 @@
             android.Manifest.permission.MODIFY_PHONE_STATE,
             android.Manifest.permission.READ_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataEnabled() {
         try {
             return isDataEnabledForReason(DATA_ENABLED_REASON_USER);
@@ -10465,6 +10595,7 @@
     @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
             android.Manifest.permission.READ_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataRoamingEnabled() {
         boolean isDataRoamingEnabled = false;
         try {
@@ -10502,6 +10633,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public @CdmaRoamingMode int getCdmaRoamingMode() {
         int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT;
         try {
@@ -10543,6 +10675,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public void setCdmaRoamingMode(@CdmaRoamingMode int mode) {
         if (getPhoneType() != PHONE_TYPE_CDMA) {
             throw new IllegalStateException("Phone does not support CDMA.");
@@ -10610,6 +10743,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public @CdmaSubscription int getCdmaSubscriptionMode() {
         int mode = CDMA_SUBSCRIPTION_RUIM_SIM;
         try {
@@ -10647,6 +10781,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public void setCdmaSubscriptionMode(@CdmaSubscription int mode) {
         if (getPhoneType() != PHONE_TYPE_CDMA) {
             throw new IllegalStateException("Phone does not support CDMA.");
@@ -10681,6 +10816,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public void setDataRoamingEnabled(boolean isEnabled) {
         try {
             ITelephony telephony = getITelephony();
@@ -10778,6 +10914,7 @@
      *
      * @return {@code true} if the DTMF tone length can be changed, and {@code false} otherwise.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean canChangeDtmfToneLength() {
         try {
             ITelephony telephony = getITelephony();
@@ -10841,6 +10978,7 @@
      *
      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
     public boolean isRttSupported() {
         try {
             ITelephony telephony = getITelephony();
@@ -10860,6 +10998,7 @@
      * @return {@code true} if the device supports hearing aid compatibility, and {@code false}
      * otherwise.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean isHearingAidCompatibilitySupported() {
         try {
             ITelephony telephony = getITelephony();
@@ -11207,6 +11346,7 @@
      **/
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void setSimPowerState(@SimPowerState int state, @NonNull Executor executor,
             @NonNull @SetSimPowerStateResult Consumer<Integer> callback) {
         setSimPowerStateForSlot(getSlotIndex(), state, executor, callback);
@@ -11236,6 +11376,7 @@
      **/
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void setSimPowerStateForSlot(int slotIndex, @SimPowerState int state,
             @NonNull Executor executor,
             @NonNull @SetSimPowerStateResult Consumer<Integer> callback) {
@@ -11450,6 +11591,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public @Nullable ComponentName getAndUpdateDefaultRespondViaMessageApplication() {
         return SmsApplication.getDefaultRespondViaMessageApplication(mContext, true);
     }
@@ -11462,6 +11604,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
     public @Nullable ComponentName getDefaultRespondViaMessageApplication() {
         return SmsApplication.getDefaultRespondViaMessageApplication(mContext, false);
     }
@@ -11657,6 +11800,7 @@
      *         permission.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int getSubscriptionId(@NonNull PhoneAccountHandle phoneAccountHandle) {
         int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         try {
@@ -11683,7 +11827,7 @@
             Log.d(TAG, "factoryReset: subId=" + subId);
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.factoryReset(subId);
+                telephony.factoryReset(subId, getOpPackageName());
             }
         } catch (RemoteException e) {
         }
@@ -11703,7 +11847,7 @@
             Log.d(TAG, "resetSettings: subId=" + getSubId());
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.factoryReset(getSubId());
+                telephony.factoryReset(getSubId(), getOpPackageName());
             }
         } catch (RemoteException e) {
         }
@@ -11723,6 +11867,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @Nullable public Locale getSimLocale() {
         try {
             final ITelephony telephony = getITelephony();
@@ -11921,6 +12066,7 @@
             Manifest.permission.READ_PHONE_STATE,
             Manifest.permission.ACCESS_COARSE_LOCATION
     })
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @Nullable ServiceState getServiceState() {
         return getServiceState(false, false);
     }
@@ -12011,6 +12157,7 @@
      * @return The URI for the ringtone to play when receiving a voicemail from a specific
      * PhoneAccount. May be {@code null} if no ringtone is set.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public @Nullable Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
         try {
             ITelephony service = getITelephony();
@@ -12038,6 +12185,7 @@
      * @deprecated Use {@link android.provider.Settings#ACTION_CHANNEL_NOTIFICATION_SETTINGS}
      * instead.
      */
+    @Deprecated
     public void setVoicemailRingtoneUri(PhoneAccountHandle phoneAccountHandle, Uri uri) {
         try {
             ITelephony service = getITelephony();
@@ -12056,6 +12204,7 @@
      * voicemail vibration setting.
      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
         try {
             ITelephony service = getITelephony();
@@ -12083,6 +12232,7 @@
      * @deprecated Use {@link android.provider.Settings#ACTION_CHANNEL_NOTIFICATION_SETTINGS}
      * instead.
      */
+    @Deprecated
     public void setVoicemailVibrationEnabled(PhoneAccountHandle phoneAccountHandle,
             boolean enabled) {
         try {
@@ -12109,6 +12259,7 @@
      * @return Carrier id of the current subscription. Return {@link #UNKNOWN_CARRIER_ID} if the
      * subscription is unavailable or the carrier cannot be identified.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int getSimCarrierId() {
         try {
             ITelephony service = getITelephony();
@@ -12133,6 +12284,7 @@
      * @return Carrier name of the current subscription. Return {@code null} if the subscription is
      * unavailable or the carrier cannot be identified.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @Nullable CharSequence getSimCarrierIdName() {
         try {
             ITelephony service = getITelephony();
@@ -12170,6 +12322,7 @@
      * Return {@link #UNKNOWN_CARRIER_ID} if the subscription is unavailable or the carrier cannot
      * be identified.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int getSimSpecificCarrierId() {
         try {
             ITelephony service = getITelephony();
@@ -12195,6 +12348,7 @@
      * @return user-facing name of the subscription specific carrier id. Return {@code null} if the
      * subscription is unavailable or the carrier cannot be identified.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @Nullable CharSequence getSimSpecificCarrierIdName() {
         try {
             ITelephony service = getITelephony();
@@ -12222,6 +12376,7 @@
      * @return matching carrier id from sim MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the
      * subscription is unavailable or the carrier cannot be identified.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public int getCarrierIdFromSimMccMnc() {
         try {
             ITelephony service = getITelephony();
@@ -12300,6 +12455,7 @@
     @Nullable
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public String getAidForAppType(@UiccAppType int appType) {
         return getAidForAppType(getSubId(), appType);
     }
@@ -12362,6 +12518,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
     public String getCdmaPrlVersion() {
         return getCdmaPrlVersion(getSubId());
     }
@@ -12427,6 +12584,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)
     public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
         if (carriers == null || !SubscriptionManager.isValidPhoneId(slotIndex)) {
             return -1;
@@ -12553,6 +12711,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @SetCarrierRestrictionResult
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)
     public int setCarrierRestrictionRules(@NonNull CarrierRestrictionRules rules) {
         try {
             ITelephony service = getITelephony();
@@ -12610,6 +12769,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)
     @Nullable
     public CarrierRestrictionRules getCarrierRestrictionRules() {
         try {
@@ -12669,6 +12829,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void setRadioEnabled(boolean enabled) {
         try {
             ITelephony service = getITelephony();
@@ -12790,6 +12951,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void reportDefaultNetworkStatus(boolean report) {
         try {
             ITelephony service = getITelephony();
@@ -12815,6 +12977,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void resetAllCarrierActions() {
         try {
             ITelephony service = getITelephony();
@@ -12934,6 +13097,7 @@
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public void setDataEnabledForReason(@DataEnabledReason int reason, boolean enabled) {
         setDataEnabledForReason(getSubId(), reason, enabled);
     }
@@ -12943,7 +13107,7 @@
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                service.setDataEnabledForReason(subId, reason, enabled);
+                service.setDataEnabledForReason(subId, reason, enabled, getOpPackageName());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -12980,6 +13144,7 @@
             android.Manifest.permission.MODIFY_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE
     })
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataEnabledForReason(@DataEnabledReason int reason) {
         return isDataEnabledForReason(getSubId(), reason);
     }
@@ -13033,6 +13198,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean getEmergencyCallbackMode() {
         return getEmergencyCallbackMode(getSubId());
     }
@@ -13071,6 +13237,7 @@
     @SuppressAutoDoc // No support carrier privileges (b/72967236).
     @RequiresPermission(anyOf = {android.Manifest.permission.READ_PRECISE_PHONE_STATE,
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isManualNetworkSelectionAllowed() {
         try {
             ITelephony telephony = getITelephony();
@@ -13091,6 +13258,7 @@
      * @return the most recent cached signal strength info from the modem
      */
     @Nullable
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public SignalStrength getSignalStrength() {
         try {
             ITelephony service = getITelephony();
@@ -13119,6 +13287,7 @@
             android.Manifest.permission.READ_PHONE_STATE,
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_BASIC_PHONE_STATE})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataConnectionAllowed() {
         boolean retVal = false;
         try {
@@ -13139,6 +13308,7 @@
      * data connections over the telephony network.
      * <p>
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataCapable() {
         if (mContext == null) return true;
         return mContext.getResources().getBoolean(
@@ -13286,6 +13456,7 @@
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean setOpportunisticNetworkState(boolean enable) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean ret = false;
@@ -13314,6 +13485,7 @@
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isOpportunisticNetworkEnabled() {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean isEnabled = false;
@@ -13429,7 +13601,11 @@
      */
     public static final long NETWORK_TYPE_BITMASK_LTE = (1 << (NETWORK_TYPE_LTE -1));
     /**
+     * NOT USED; this bitmask is exposed accidentally, will be deprecated in U.
+     * If used, will be converted to {@link #NETWORK_TYPE_BITMASK_LTE}.
      * network type bitmask indicating the support of radio tech LTE CA (carrier aggregation).
+     *
+     * @see #NETWORK_TYPE_BITMASK_LTE
      */
     public static final long NETWORK_TYPE_BITMASK_LTE_CA = (1 << (NETWORK_TYPE_LTE_CA -1));
 
@@ -13501,6 +13677,7 @@
      * @throws SecurityException if the caller does not have the required permission
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @NetworkTypeBitMask long getSupportedRadioAccessFamily() {
         try {
             ITelephony telephony = getITelephony();
@@ -13536,6 +13713,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @SystemApi
     public void notifyOtaEmergencyNumberDbInstalled() {
         try {
@@ -13562,6 +13740,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @SystemApi
     public void updateOtaEmergencyNumberDbFilePath(
             @NonNull ParcelFileDescriptor otaParcelFileDescriptor) {
@@ -13587,6 +13766,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     @SystemApi
     public void resetOtaEmergencyNumberDbFilePath() {
         try {
@@ -13646,6 +13826,7 @@
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @NonNull
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList() {
         Map<Integer, List<EmergencyNumber>> emergencyNumberList = new HashMap<>();
         try {
@@ -13701,6 +13882,7 @@
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @NonNull
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
             @EmergencyServiceCategories int categories) {
         Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
@@ -13766,6 +13948,7 @@
      * SIM card(s), Android database, modem, network or defaults; {@code false} otherwise.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean isEmergencyNumber(@NonNull String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -13805,6 +13988,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public boolean isPotentialEmergencyNumber(@NonNull String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -13830,6 +14014,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public int getEmergencyNumberDbVersion() {
         try {
             ITelephony telephony = getITelephony();
@@ -13970,6 +14155,7 @@
      *                 See {@link TelephonyManager.SetOpportunisticSubscriptionResult}
      *                 for more details. Pass null if don't care about the result.
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public void setPreferredOpportunisticDataSubscription(int subId, boolean needValidation,
             @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
@@ -14033,6 +14219,7 @@
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_PHONE_STATE
     })
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public int getPreferredOpportunisticDataSubscription() {
         String packageName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         String attributionTag = mContext != null ? mContext.getAttributionTag() : null;
@@ -14068,6 +14255,7 @@
      *
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void updateAvailableNetworks(@NonNull List<AvailableNetworkInfo> availableNetworks,
             @Nullable @CallbackExecutor Executor executor,
             @UpdateAvailableNetworksResult @Nullable Consumer<Integer> callback) {
@@ -14218,6 +14406,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CARRIERLOCK)
     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
         try {
             ITelephony service = getITelephony();
@@ -14271,6 +14460,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @IsMultiSimSupportedResult
     public int isMultiSimSupported() {
         if (getSupportedModemCount() < 2) {
@@ -14301,6 +14491,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void switchMultiSimConfig(int numOfSims) {
         try {
             ITelephony telephony = getITelephony();
@@ -14326,6 +14517,7 @@
      * configurations, otherwise return {@code false}.
      */
     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean doesSwitchMultiSimConfigTriggerReboot() {
         try {
             ITelephony service = getITelephony();
@@ -14378,6 +14570,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @CarrierPrivilegeStatus int getCarrierPrivilegeStatus(int uid) {
         try {
             ITelephony telephony = getITelephony();
@@ -14491,6 +14684,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isDataEnabledForApn(@ApnType int apnType) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         try {
@@ -14512,6 +14706,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isApnMetered(@ApnType int apnType) {
         try {
             ITelephony service = getITelephony();
@@ -14540,6 +14735,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull Consumer<Boolean> callback) {
@@ -14557,6 +14753,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers) {
         Objects.requireNonNull(specifiers, "Specifiers must not be null.");
         setSystemSelectionChannelsInternal(specifiers, null, null);
@@ -14603,6 +14800,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @NonNull List<RadioAccessSpecifier> getSystemSelectionChannels() {
         try {
             ITelephony service = getITelephony();
@@ -14630,6 +14828,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public boolean matchesCurrentSimOperator(@NonNull String mccmnc, @MvnoType int mvnoType,
             @Nullable String mvnoMatchData) {
         try {
@@ -14720,6 +14919,7 @@
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void getCallForwarding(@CallForwardingReason int callForwardingReason,
             @NonNull Executor executor, @NonNull CallForwardingInfoCallback callback) {
         if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL
@@ -14795,6 +14995,7 @@
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo,
             @Nullable @CallbackExecutor Executor executor,
             @Nullable @CallForwardingInfoCallback.CallForwardingError
@@ -14907,6 +15108,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void getCallWaitingStatus(@NonNull Executor executor,
             @NonNull @CallWaitingStatus Consumer<Integer> resultListener) {
         Objects.requireNonNull(executor);
@@ -14955,6 +15157,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
     public void setCallWaitingEnabled(boolean enabled, @Nullable Executor executor,
             @Nullable Consumer<Integer> resultListener) {
         if (resultListener != null) {
@@ -15036,6 +15239,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public void setMobileDataPolicyEnabled(@MobileDataPolicy int policy, boolean enabled) {
         try {
             ITelephony service = getITelephony();
@@ -15056,6 +15260,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_DATA)
     public boolean isMobileDataPolicyEnabled(@MobileDataPolicy int policy) {
         try {
             ITelephony service = getITelephony();
@@ -15090,6 +15295,7 @@
      */
     @WorkerThread
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     @SystemApi
     public boolean isIccLockEnabled() {
         try {
@@ -15124,6 +15330,7 @@
     @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public PinResult setIccLockEnabled(boolean enabled, @NonNull String pin) {
         checkNotNull(pin, "setIccLockEnabled pin can't be null.");
         try {
@@ -15165,6 +15372,7 @@
     @SystemApi
     @NonNull
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public PinResult changeIccLockPin(@NonNull String oldPin, @NonNull String newPin) {
         checkNotNull(oldPin, "changeIccLockPin oldPin can't be null.");
         checkNotNull(newPin, "changeIccLockPin newPin can't be null.");
@@ -15557,6 +15765,7 @@
      *
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public @NonNull List<String> getEquivalentHomePlmns() {
         try {
             ITelephony telephony = getITelephony();
@@ -15670,6 +15879,7 @@
      * @param capability the name of the capability to check for
      * @return the availability of the capability
      */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public boolean isRadioInterfaceCapabilitySupported(
             @NonNull @RadioInterfaceCapability String capability) {
         try {
@@ -15791,6 +16001,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     @ThermalMitigationResult
     public int sendThermalMitigationRequest(
             @NonNull ThermalMitigationRequest thermalMitigationRequest) {
@@ -16062,6 +16273,7 @@
     @WorkerThread
     @RequiresPermission(anyOf = {android.Manifest.permission.MODIFY_PHONE_STATE,
             Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION})
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
     public void bootstrapAuthenticationRequest(
             @UiccAppTypeExt int appType, @NonNull Uri nafId,
             @NonNull UaSecurityProtocolIdentifier securityProtocol,
@@ -16156,6 +16368,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void setSignalStrengthUpdateRequest(@NonNull SignalStrengthUpdateRequest request) {
         Objects.requireNonNull(request, "request must not be null");
 
@@ -16185,6 +16398,7 @@
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public void clearSignalStrengthUpdateRequest(@NonNull SignalStrengthUpdateRequest request) {
         Objects.requireNonNull(request, "request must not be null");
 
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 122662d..e0c5298 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -19,6 +19,8 @@
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -42,6 +44,7 @@
 /**
  * Manages the radio access network scan requests and callbacks.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
 public final class TelephonyScanManager {
 
     private static final String TAG = "TelephonyScanManager";
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b0ddf2c..a710e38 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1290,8 +1290,8 @@
                 && Objects.equals(this.mOperatorNumeric, other.mOperatorNumeric)
                 && Objects.equals(this.mProtocol, other.mProtocol)
                 && Objects.equals(this.mRoamingProtocol, other.mRoamingProtocol)
-                && xorEqualsInt(this.mMtuV4, other.mMtuV4)
-                && xorEqualsInt(this.mMtuV6, other.mMtuV6)
+                && mtuUnsetOrEquals(this.mMtuV4, other.mMtuV4)
+                && mtuUnsetOrEquals(this.mMtuV6, other.mMtuV6)
                 && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled)
                 && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
                 && Objects.equals(this.mLingeringNetworkTypeBitmask,
@@ -1319,7 +1319,12 @@
     // Equal or one is not specified.
     private boolean xorEqualsInt(int first, int second) {
         return first == UNSPECIFIED_INT || second == UNSPECIFIED_INT
-            || Objects.equals(first, second);
+                || first == second;
+    }
+
+    // Equal or one is not specified. Specific to MTU where <= 0 indicates unset.
+    private boolean mtuUnsetOrEquals(int first, int second) {
+        return first <= 0 || second <= 0 || first == second;
     }
 
     private String nullToEmpty(String stringValue) {
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index ef02589..4afaf53 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -428,7 +428,7 @@
     public String toString() {
         StringBuffer sb = new StringBuffer();
         sb.append("DataCallResponse: {")
-           .append(" cause=").append(mCause)
+           .append(" cause=").append(DataFailCause.toString(mCause))
            .append(" retry=").append(mSuggestedRetryTime)
            .append(" cid=").append(mId)
            .append(" linkStatus=").append(mLinkStatus)
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index bd346d5..700d615 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -41,6 +41,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -351,7 +352,7 @@
         public void requestDataCallList(@NonNull DataServiceCallback callback) {
             // The default implementation is to return unsupported.
             callback.onRequestDataCallListComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED,
-                    null);
+                    Collections.EMPTY_LIST);
         }
 
         private void registerForDataCallListChanged(IDataServiceCallback callback) {
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index ab35d77..4452d1c 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -19,8 +19,10 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.service.euicc.EuiccProfileInfo;
@@ -61,6 +63,7 @@
  * @hide
  */
 @SystemApi
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
 public class EuiccCardManager {
     private static final String TAG = "EuiccCardManager";
 
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index a1e4f29..a49a61b5 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
@@ -54,6 +55,7 @@
  *
  * <p>See {@link #isEnabled} before attempting to use these APIs.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
 public class EuiccManager {
 
     /**
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 82d64ab..5bae1ad 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -21,11 +21,13 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -61,6 +63,7 @@
  * Use {@link android.telephony.ims.ImsManager#getImsMmTelManager(int)} to get an instance of this
  * manager.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public class ImsMmTelManager implements RegistrationManager {
     private static final String TAG = "ImsMmTelManager";
 
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 1b047c7..3415868 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -19,11 +19,13 @@
 import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -53,6 +55,7 @@
  *
  * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public class ImsRcsManager {
     private static final String TAG = "ImsRcsManager";
 
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 5aef8a6..677c1a9 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -20,6 +20,7 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.StringDef;
@@ -55,6 +56,7 @@
  * applications and may vary. It is up to the carrier and OEM applications to ensure that the
  * correct provisioning keys are being used when integrating with a vendor's ImsService.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public class ProvisioningManager {
 
     private static final String TAG = "ProvisioningManager";
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index a2015cd..090d413 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -21,7 +21,9 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -42,6 +44,7 @@
 /**
  * Manages IMS Service registration state for associated {@link ImsFeature}s.
  */
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public interface RegistrationManager {
 
     /**
diff --git a/telephony/java/android/telephony/ims/SipDelegateManager.java b/telephony/java/android/telephony/ims/SipDelegateManager.java
index f913df5..94e9afb 100644
--- a/telephony/java/android/telephony/ims/SipDelegateManager.java
+++ b/telephony/java/android/telephony/ims/SipDelegateManager.java
@@ -21,6 +21,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.Context;
@@ -57,6 +58,7 @@
  * @hide
  */
 @SystemApi
+@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION)
 public class SipDelegateManager {
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7799113..f5877d8 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -270,13 +270,13 @@
      * Allow mobile data connections.
      */
     @UnsupportedAppUsage
-    boolean enableDataConnectivity();
+    boolean enableDataConnectivity(String callingPackage);
 
     /**
      * Disallow mobile data connections.
      */
     @UnsupportedAppUsage
-    boolean disableDataConnectivity();
+    boolean disableDataConnectivity(String callingPackage);
 
     /**
      * Report whether data connectivity is possible.
@@ -959,8 +959,9 @@
      * @param subId user preferred subId.
      * @param reason the reason the data enable change is taking place
      * @param enable true to turn on, else false
+     * @param callingPackage the package that changed the data enabled state
      */
-     void setDataEnabledForReason(int subId, int reason, boolean enable);
+     void setDataEnabledForReason(int subId, int reason, boolean enable, String callingPackage);
 
     /**
      * Return whether data is enabled for certain reason
@@ -978,14 +979,6 @@
      boolean isManualNetworkSelectionAllowed(int subId);
 
     /**
-     * Get P-CSCF address from PCO after data connection is established or modified.
-     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
-     * @param callingPackage The package making the call.
-     * @param callingFeatureId The feature in the package.
-     */
-    String[] getPcscfAddress(String apnType, String callingPackage, String callingFeatureId);
-
-    /**
      * Set IMS registration state
      */
     void setImsRegistrationState(boolean registered);
@@ -1340,7 +1333,7 @@
      */
     PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId);
 
-    void factoryReset(int subId);
+    void factoryReset(int subId, String callingPackage);
 
     /**
      * Returns users's current locale based on the SIM.
diff --git a/tests/ApkVerityTest/AndroidTest.xml b/tests/ApkVerityTest/AndroidTest.xml
index 55704ed..3c8e1ed 100644
--- a/tests/ApkVerityTest/AndroidTest.xml
+++ b/tests/ApkVerityTest/AndroidTest.xml
@@ -35,6 +35,8 @@
         <option name="push" value="ApkVerityTestCert.der->/data/local/tmp/ApkVerityTestCert.der" />
     </target_preparer>
 
+    <!-- Skip on HWASan. TODO(b/232288278): Re-enable -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.SkipHWASanModuleController" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="ApkVerityTest.jar" />
     </test>
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 5f606e1..09080be 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -26,6 +26,7 @@
 
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
+import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -50,9 +51,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.vcn.VcnManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
+import android.os.PersistableBundle;
 import android.os.test.TestLooper;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
@@ -104,6 +107,26 @@
         TEST_SUBID_TO_INFO_MAP = Collections.unmodifiableMap(subIdToGroupMap);
     }
 
+    private static final String TEST_CARRIER_CONFIG_KEY_1 = "TEST_CARRIER_CONFIG_KEY_1";
+    private static final String TEST_CARRIER_CONFIG_KEY_2 = "TEST_CARRIER_CONFIG_KEY_2";
+    private static final PersistableBundle TEST_CARRIER_CONFIG = new PersistableBundle();
+    private static final PersistableBundleWrapper TEST_CARRIER_CONFIG_WRAPPER;
+    private static final Map<Integer, PersistableBundleWrapper> TEST_SUBID_TO_CARRIER_CONFIG_MAP;
+
+    static {
+        TEST_CARRIER_CONFIG.putString(
+                VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
+                VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY);
+        TEST_CARRIER_CONFIG.putString(
+                VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
+                VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY);
+        TEST_CARRIER_CONFIG_WRAPPER = new PersistableBundleWrapper(TEST_CARRIER_CONFIG);
+
+        final Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
+        subIdToCarrierConfigMap.put(TEST_SUBSCRIPTION_ID_1, TEST_CARRIER_CONFIG_WRAPPER);
+        TEST_SUBID_TO_CARRIER_CONFIG_MAP = Collections.unmodifiableMap(subIdToCarrierConfigMap);
+    }
+
     @NonNull private final Context mContext;
     @NonNull private final TestLooper mTestLooper;
     @NonNull private final Handler mHandler;
@@ -144,6 +167,9 @@
         doReturn(mCarrierConfigManager)
                 .when(mContext)
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        doReturn(TEST_CARRIER_CONFIG)
+                .when(mCarrierConfigManager)
+                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
 
         // subId 1, 2 are in same subGrp, only subId 1 is active
         doReturn(TEST_PARCEL_UUID).when(TEST_SUBINFO_1).getGroupUuid();
@@ -227,14 +253,24 @@
     private TelephonySubscriptionSnapshot buildExpectedSnapshot(
             Map<Integer, SubscriptionInfo> subIdToInfoMap,
             Map<ParcelUuid, Set<String>> privilegedPackages) {
-        return new TelephonySubscriptionSnapshot(0, subIdToInfoMap, privilegedPackages);
+        return buildExpectedSnapshot(0, subIdToInfoMap, privilegedPackages);
     }
 
     private TelephonySubscriptionSnapshot buildExpectedSnapshot(
             int activeSubId,
             Map<Integer, SubscriptionInfo> subIdToInfoMap,
             Map<ParcelUuid, Set<String>> privilegedPackages) {
-        return new TelephonySubscriptionSnapshot(activeSubId, subIdToInfoMap, privilegedPackages);
+        return buildExpectedSnapshot(
+                activeSubId, subIdToInfoMap, TEST_SUBID_TO_CARRIER_CONFIG_MAP, privilegedPackages);
+    }
+
+    private TelephonySubscriptionSnapshot buildExpectedSnapshot(
+            int activeSubId,
+            Map<Integer, SubscriptionInfo> subIdToInfoMap,
+            Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap,
+            Map<ParcelUuid, Set<String>> privilegedPackages) {
+        return new TelephonySubscriptionSnapshot(
+                activeSubId, subIdToInfoMap, subIdToCarrierConfigMap, privilegedPackages);
     }
 
     private void verifyNoActiveSubscriptions() {
@@ -245,6 +281,8 @@
     private void setupReadySubIds() {
         mTelephonySubscriptionTracker.setReadySubIdsBySlotId(
                 Collections.singletonMap(TEST_SIM_SLOT_INDEX, TEST_SUBSCRIPTION_ID_1));
+        mTelephonySubscriptionTracker.setSubIdToCarrierConfigMap(
+                Collections.singletonMap(TEST_SUBSCRIPTION_ID_1, TEST_CARRIER_CONFIG_WRAPPER));
     }
 
     private void setPrivilegedPackagesForMock(@NonNull List<String> privilegedPackages) {
@@ -300,6 +338,7 @@
         readySubIdsBySlotId.put(TEST_SIM_SLOT_INDEX + 1, TEST_SUBSCRIPTION_ID_1);
 
         mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId);
+        mTelephonySubscriptionTracker.setSubIdToCarrierConfigMap(TEST_SUBID_TO_CARRIER_CONFIG_MAP);
         doReturn(1).when(mTelephonyManager).getActiveModemCount();
 
         List<CarrierPrivilegesCallback> carrierPrivilegesCallbacks =
@@ -464,8 +503,16 @@
 
         mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
         mTestLooper.dispatchAll();
-        verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(emptyMap())));
+        verify(mCallback)
+                .onNewSnapshot(
+                        eq(
+                                buildExpectedSnapshot(
+                                        0, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap())));
         assertNull(mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
+        assertNull(
+                mTelephonySubscriptionTracker
+                        .getSubIdToCarrierConfigMap()
+                        .get(TEST_SUBSCRIPTION_ID_1));
     }
 
     @Test
@@ -493,7 +540,7 @@
     public void testTelephonySubscriptionSnapshotGetGroupForSubId() throws Exception {
         final TelephonySubscriptionSnapshot snapshot =
                 new TelephonySubscriptionSnapshot(
-                        TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
+                        TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap());
 
         assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_1));
         assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_2));
@@ -503,7 +550,7 @@
     public void testTelephonySubscriptionSnapshotGetAllSubIdsInGroup() throws Exception {
         final TelephonySubscriptionSnapshot snapshot =
                 new TelephonySubscriptionSnapshot(
-                        TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
+                        TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap());
 
         assertEquals(
                 new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index 3d95a9b..785bff1 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -138,6 +138,7 @@
             new TelephonySubscriptionSnapshot(
                     TEST_SUB_ID,
                     Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO),
+                    Collections.EMPTY_MAP,
                     Collections.EMPTY_MAP);
 
     @NonNull protected final Context mContext;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 6c849b5..b0d6895 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -30,6 +30,7 @@
 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesPriorityRule;
 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesWifiPriorityRule;
 import static com.android.server.vcn.routeselection.UnderlyingNetworkControllerTest.getLinkPropertiesWithName;
+import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -309,7 +310,9 @@
                         wifiNetworkPriority,
                         mWifiNetworkRecord,
                         selectedNetworkRecord,
-                        carrierConfig));
+                        carrierConfig == null
+                                ? null
+                                : new PersistableBundleWrapper(carrierConfig)));
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/vcn/util/PersistableBundleUtilsTest.java b/tests/vcn/java/com/android/server/vcn/util/PersistableBundleUtilsTest.java
index a44a734..9c6d852 100644
--- a/tests/vcn/java/com/android/server/vcn/util/PersistableBundleUtilsTest.java
+++ b/tests/vcn/java/com/android/server/vcn/util/PersistableBundleUtilsTest.java
@@ -18,6 +18,8 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.os.PersistableBundle;
 
@@ -211,4 +213,93 @@
 
         assertEquals(testInt, result);
     }
+
+    private PersistableBundle getTestBundle() {
+        final PersistableBundle bundle = new PersistableBundle();
+
+        bundle.putBoolean(TEST_KEY + "Boolean", true);
+        bundle.putBooleanArray(TEST_KEY + "BooleanArray", new boolean[] {true, false});
+        bundle.putDouble(TEST_KEY + "Double", 0.1);
+        bundle.putDoubleArray(TEST_KEY + "DoubleArray", new double[] {0.1, 0.2, 0.3});
+        bundle.putInt(TEST_KEY + "Int", 1);
+        bundle.putIntArray(TEST_KEY + "IntArray", new int[] {1, 2});
+        bundle.putLong(TEST_KEY + "Long", 5L);
+        bundle.putLongArray(TEST_KEY + "LongArray", new long[] {0L, -1L, -2L});
+        bundle.putString(TEST_KEY + "String", "TEST");
+        bundle.putStringArray(TEST_KEY + "StringArray", new String[] {"foo", "bar", "bas"});
+        bundle.putPersistableBundle(
+                TEST_KEY + "PersistableBundle",
+                new TestClass(1, TEST_INT_ARRAY, TEST_STRING_PREFIX, new PersistableBundle())
+                        .toPersistableBundle());
+
+        return bundle;
+    }
+
+    @Test
+    public void testMinimizeBundle() throws Exception {
+        final String[] minimizedKeys =
+                new String[] {
+                    TEST_KEY + "Boolean",
+                    TEST_KEY + "BooleanArray",
+                    TEST_KEY + "Double",
+                    TEST_KEY + "DoubleArray",
+                    TEST_KEY + "Int",
+                    TEST_KEY + "IntArray",
+                    TEST_KEY + "Long",
+                    TEST_KEY + "LongArray",
+                    TEST_KEY + "String",
+                    TEST_KEY + "StringArray",
+                    TEST_KEY + "PersistableBundle"
+                };
+
+        final PersistableBundle testBundle = getTestBundle();
+        testBundle.putBoolean(TEST_KEY + "Boolean2", true);
+
+        final PersistableBundle minimized =
+                PersistableBundleUtils.minimizeBundle(testBundle, minimizedKeys);
+
+        // Verify that the minimized bundle is NOT the same in size OR values due to the extra
+        // Boolean2 key
+        assertFalse(PersistableBundleUtils.isEqual(testBundle, minimized));
+
+        // Verify that removing the extra key from the source bundle results in equality.
+        testBundle.remove(TEST_KEY + "Boolean2");
+        assertTrue(PersistableBundleUtils.isEqual(testBundle, minimized));
+    }
+
+    @Test
+    public void testToFromDiskStableBytes() throws Exception {
+        final PersistableBundle testBundle = getTestBundle();
+        final PersistableBundle result =
+                PersistableBundleUtils.fromDiskStableBytes(
+                        PersistableBundleUtils.toDiskStableBytes(testBundle));
+        assertTrue(PersistableBundleUtils.isEqual(testBundle, result));
+    }
+
+    @Test
+    public void testEquality_identical() throws Exception {
+        final PersistableBundle left = getTestBundle();
+        final PersistableBundle right = getTestBundle();
+
+        assertTrue(PersistableBundleUtils.isEqual(left, right));
+    }
+
+    @Test
+    public void testEquality_different() throws Exception {
+        final PersistableBundle left = getTestBundle();
+        final PersistableBundle right = getTestBundle();
+
+        left.putBoolean(TEST_KEY + "Boolean2", true);
+        assertFalse(PersistableBundleUtils.isEqual(left, right));
+
+        left.remove(TEST_KEY + "Boolean2");
+        assertTrue(PersistableBundleUtils.isEqual(left, right));
+    }
+
+    @Test
+    public void testEquality_null() throws Exception {
+        assertFalse(PersistableBundleUtils.isEqual(getTestBundle(), null));
+        assertFalse(PersistableBundleUtils.isEqual(null, getTestBundle()));
+        assertTrue(PersistableBundleUtils.isEqual(null, null));
+    }
 }
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 7ea4ab1..0aca293 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -27,7 +27,7 @@
 
 static ApiVersion sDevelopmentSdkLevel = 10000;
 static const auto sDevelopmentSdkCodeNames =
-    std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu"});
+    std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu", "UpsideDownCake"});
 
 static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
     {0x021c, 1},
diff --git a/tools/bit/adb.cpp b/tools/bit/adb.cpp
index f521a63..201028b 100644
--- a/tools/bit/adb.cpp
+++ b/tools/bit/adb.cpp
@@ -73,7 +73,7 @@
 get_system_property(const string& name, int* err)
 {
     Command cmd("adb");
-    cmd.AddArg("shell");
+    cmd.AddArg("exec-out");
     cmd.AddArg("getprop");
     cmd.AddArg(name);
 
@@ -278,7 +278,7 @@
         InstrumentationCallbacks* callbacks)
 {
     Command cmd("adb");
-    cmd.AddArg("shell");
+    cmd.AddArg("exec-out");
     cmd.AddArg("am");
     cmd.AddArg("instrument");
     cmd.AddArg("-w");
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index fd184f5..0d48070 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -52,24 +52,22 @@
 
     int testPassCount;
     int testFailCount;
+    int testIgnoreCount;
     int unknownFailureCount; // unknown failure == "Process crashed", etc.
-    bool actionsWithNoTests;
 
     Target(bool b, bool i, bool t, const string& p);
 };
 
 Target::Target(bool b, bool i, bool t, const string& p)
-    :build(b),
-     install(i),
-     test(t),
-     pattern(p),
-     testActionCount(0),
-     testPassCount(0),
-     testFailCount(0),
-     unknownFailureCount(0),
-     actionsWithNoTests(false)
-{
-}
+      : build(b),
+        install(i),
+        test(t),
+        pattern(p),
+        testActionCount(0),
+        testPassCount(0),
+        testFailCount(0),
+        testIgnoreCount(0),
+        unknownFailureCount(0) {}
 
 /**
  * Command line options.
@@ -188,13 +186,12 @@
 
     // The number of tests that failed
     int failCount;
+
+    // The number of tests that were ignored (because of @Ignore)
+    int ignoreCount;
 };
 
-TestAction::TestAction()
-    :passCount(0),
-     failCount(0)
-{
-}
+TestAction::TestAction() : passCount(0), failCount(0), ignoreCount(0) {}
 
 /**
  * Record for an activity that is going to be launched.
@@ -278,7 +275,7 @@
                 line << " of " << testCount;
             }
         }
-        line << ": " << m_currentAction->target->name << ':' << className << "\\#" << testName;
+        line << ": " << m_currentAction->target->name << ':' << className << "#" << testName;
         print_one_line("%s", line.str().c_str());
     } else if ((resultCode == -1) || (resultCode == -2)) {
         // test failed
@@ -286,9 +283,9 @@
         // all as "failures".
         m_currentAction->failCount++;
         m_currentAction->target->testFailCount++;
-        printf("%s\n%sFailed: %s:%s\\#%s%s\n", g_escapeClearLine, g_escapeRedBold,
-                m_currentAction->target->name.c_str(), className.c_str(),
-                testName.c_str(), g_escapeEndColor);
+        printf("%s\n%sFailed: %s:%s#%s%s\n", g_escapeClearLine, g_escapeRedBold,
+               m_currentAction->target->name.c_str(), className.c_str(), testName.c_str(),
+               g_escapeEndColor);
 
         bool stackFound;
         string stack = get_bundle_string(results, &stackFound, "stack", NULL);
@@ -300,6 +297,13 @@
         } else if (stackFound) {
             printf("%s\n", stack.c_str());
         }
+    } else if (resultCode == -3) {
+        // test ignored
+        m_currentAction->ignoreCount++;
+        m_currentAction->target->testIgnoreCount++;
+        printf("%s\n%sIgnored: %s:%s#%s%s\n", g_escapeClearLine, g_escapeYellowBold,
+               m_currentAction->target->name.c_str(), className.c_str(), testName.c_str(),
+               g_escapeEndColor);
     }
 }
 
@@ -403,11 +407,14 @@
     fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs all the\n");
     fprintf(out, "      tests in the ProtoOutputStreamBoolTest class.\n");
     fprintf(out, "\n");
-    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite\n");
+    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest#testWrite\n");
     fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
     fprintf(out, "      test method on that class.\n");
     fprintf(out, "\n");
-    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite,.ProtoOutputStreamBoolTest\\#testRepeated\n");
+    fprintf(out,
+            "    bit "
+            "CtsProtoTestCases:.ProtoOutputStreamBoolTest#testWrite,.ProtoOutputStreamBoolTest#"
+            "testRepeated\n");
     fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
     fprintf(out, "      and testRepeated test methods on that class.\n");
     fprintf(out, "\n");
@@ -450,6 +457,35 @@
     fprintf(out, "\n");
 }
 
+/**
+ * Prints a possibly color-coded summary of test results. Example output:
+ *
+ *     "34 passed, 0 failed, 1 ignored\n"
+ */
+static void print_results(int passed, int failed, int ignored) {
+    char const* nothing = "";
+    char const* cp = nothing;
+    char const* cf = nothing;
+    char const* ci = nothing;
+
+    if (failed > 0) {
+        cf = g_escapeRedBold;
+    } else if (passed > 0 || ignored > 0) {
+        cp = passed > 0 ? g_escapeGreenBold : nothing;
+        ci = ignored > 0 ? g_escapeYellowBold : nothing;
+    } else {
+        cp = g_escapeYellowBold;
+        cf = g_escapeYellowBold;
+    }
+
+    if (ignored > 0) {
+        printf("%s%d passed%s, %s%d failed%s, %s%d ignored%s\n", cp, passed, g_escapeEndColor, cf,
+               failed, g_escapeEndColor, ci, ignored, g_escapeEndColor);
+    } else {
+        printf("%s%d passed%s, %s%d failed%s\n", cp, passed, g_escapeEndColor, cf, failed,
+               g_escapeEndColor);
+    }
+}
 
 /**
  * Sets the appropriate flag* variables. If there is a problem with the
@@ -812,7 +848,7 @@
 
             // Stop & Sync
             if (!options.noRestart) {
-                err = run_adb("shell", "stop", NULL);
+                err = run_adb("exec-out", "stop", NULL);
                 check_error(err);
             }
             err = run_adb("remount", NULL);
@@ -831,9 +867,9 @@
                 } else {
                     print_status("Restarting the runtime");
 
-                    err = run_adb("shell", "setprop", "sys.boot_completed", "0", NULL);
+                    err = run_adb("exec-out", "setprop", "sys.boot_completed", "0", NULL);
                     check_error(err);
-                    err = run_adb("shell", "start", NULL);
+                    err = run_adb("exec-out", "start", NULL);
                     check_error(err);
                 }
 
@@ -846,7 +882,7 @@
                     sleep(2);
                 }
                 sleep(1);
-                err = run_adb("shell", "wm", "dismiss-keyguard", NULL);
+                err = run_adb("exec-out", "wm", "dismiss-keyguard", NULL);
                 check_error(err);
             }
         }
@@ -863,7 +899,7 @@
                 continue;
             }
             // TODO: if (!apk.file.fileInfo.exists || apk.file.HasChanged())
-            err = run_adb("shell", "mkdir", "-p", dir.c_str(), NULL);
+            err = run_adb("exec-out", "mkdir", "-p", dir.c_str(), NULL);
             check_error(err);
             err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str(), NULL);
             check_error(err);
@@ -945,9 +981,9 @@
                         }
                     }
                     if (runAll) {
-                        err = run_adb("shell", installedPath.c_str(), NULL);
+                        err = run_adb("exec-out", installedPath.c_str(), NULL);
                     } else {
-                        err = run_adb("shell", installedPath.c_str(), filterArg.c_str(), NULL);
+                        err = run_adb("exec-out", installedPath.c_str(), filterArg.c_str(), NULL);
                     }
                     if (err == 0) {
                         target->testPassCount++;
@@ -1035,22 +1071,10 @@
             err = run_instrumentation_test(action.packageName, action.runner, action.className,
                     &testResults);
             check_error(err);
-            if (action.passCount == 0 && action.failCount == 0) {
-                action.target->actionsWithNoTests = true;
-            }
             int total = action.passCount + action.failCount;
             printf("%sRan %d test%s for %s. ", g_escapeClearLine,
                     total, total > 1 ? "s" : "", action.target->name.c_str());
-            if (action.passCount == 0 && action.failCount == 0) {
-                printf("%s%d passed, %d failed%s\n", g_escapeYellowBold, action.passCount,
-                        action.failCount, g_escapeEndColor);
-            } else if (action.failCount >  0) {
-                printf("%d passed, %s%d failed%s\n", action.passCount, g_escapeRedBold,
-                        action.failCount, g_escapeEndColor);
-            } else {
-                printf("%s%d passed%s, %d failed\n", g_escapeGreenBold, action.passCount,
-                        g_escapeEndColor, action.failCount);
-            }
+            print_results(action.passCount, action.failCount, action.ignoreCount);
             if (!testResults.IsSuccess()) {
                 printf("\n%sTest didn't finish successfully: %s%s\n", g_escapeRedBold,
                         testResults.GetErrorMessage().c_str(), g_escapeEndColor);
@@ -1073,7 +1097,7 @@
 
         const ActivityAction& action = activityActions[0];
         string componentName = action.packageName + "/" + action.className;
-        err = run_adb("shell", "am", "start", componentName.c_str(), NULL);
+        err = run_adb("exec-out", "am", "start", componentName.c_str(), NULL);
         check_error(err);
     }
 
@@ -1147,17 +1171,11 @@
                     printf("     %sUnknown failure, see above message.%s\n",
                             g_escapeRedBold, g_escapeEndColor);
                     hasErrors = true;
-                } else if (target->actionsWithNoTests) {
-                    printf("     %s%d passed, %d failed%s\n", g_escapeYellowBold,
-                            target->testPassCount, target->testFailCount, g_escapeEndColor);
-                    hasErrors = true;
-                } else if (target->testFailCount > 0) {
-                    printf("     %d passed, %s%d failed%s\n", target->testPassCount,
-                            g_escapeRedBold, target->testFailCount, g_escapeEndColor);
-                    hasErrors = true;
                 } else {
-                    printf("     %s%d passed%s, %d failed\n", g_escapeGreenBold,
-                            target->testPassCount, g_escapeEndColor, target->testFailCount);
+                    printf("   %s%s     ", target->name.c_str(),
+                           padding.c_str() + target->name.length());
+                    print_results(target->testPassCount, target->testFailCount,
+                                  target->testIgnoreCount);
                 }
             }
         }
diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp
index 82a5dac..7059c52 100644
--- a/tools/processors/intdef_mappings/Android.bp
+++ b/tools/processors/intdef_mappings/Android.bp
@@ -7,18 +7,24 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+java_library_host {
+    name: "libintdef-annotation-processor",
+
+    srcs: [
+        ":framework-annotations",
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+
+    use_tools_jar: true,
+}
+
 java_plugin {
     name: "intdef-annotation-processor",
 
     processor_class: "android.processor.IntDefProcessor",
 
-    srcs: [
-        ":framework-annotations",
-        "src/**/*.java",
-        "src/**/*.kt"
-    ],
-
-    use_tools_jar: true,
+    static_libs: ["libintdef-annotation-processor"],
 }
 
 java_test_host {
@@ -26,8 +32,8 @@
 
     srcs: [
         "test/**/*.java",
-        "test/**/*.kt"
-     ],
+        "test/**/*.kt",
+    ],
     java_resource_dirs: ["test/resources"],
 
     static_libs: [
@@ -35,7 +41,7 @@
         "truth-prebuilt",
         "junit",
         "guava",
-        "intdef-annotation-processor"
+        "libintdef-annotation-processor",
     ],
 
     test_suites: ["general-tests"],
diff --git a/tools/processors/view_inspector/Android.bp b/tools/processors/view_inspector/Android.bp
index ea9974f..877a1d2 100644
--- a/tools/processors/view_inspector/Android.bp
+++ b/tools/processors/view_inspector/Android.bp
@@ -7,10 +7,8 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
-java_plugin {
-    name: "view-inspector-annotation-processor",
-
-    processor_class: "android.processor.view.inspector.PlatformInspectableProcessor",
+java_library_host {
+    name: "libview-inspector-annotation-processor",
 
     srcs: ["src/java/**/*.java"],
     java_resource_dirs: ["src/resources"],
@@ -23,6 +21,16 @@
     use_tools_jar: true,
 }
 
+java_plugin {
+    name: "view-inspector-annotation-processor",
+
+    processor_class: "android.processor.view.inspector.PlatformInspectableProcessor",
+
+    static_libs: [
+        "libview-inspector-annotation-processor",
+    ],
+}
+
 java_test_host {
     name: "view-inspector-annotation-processor-test",
 
@@ -32,7 +40,7 @@
     static_libs: [
         "junit",
         "guava",
-        "view-inspector-annotation-processor"
+        "libview-inspector-annotation-processor",
     ],
 
     test_suites: ["general-tests"],
diff --git a/tools/validatekeymaps/OWNERS b/tools/validatekeymaps/OWNERS
index 0313a40..4c20c4d 100644
--- a/tools/validatekeymaps/OWNERS
+++ b/tools/validatekeymaps/OWNERS
@@ -1,2 +1 @@
-michaelwr@google.com
-svv@google.com
+include /INPUT_OWNERS