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—not the left
+ * edge of the window—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—not the top edge
+ * of the window—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