Merge "Fix clock disappearing from locksscreen" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 2047168..eed248b 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -310,6 +310,8 @@
 aconfig_declarations {
     name: "android.os.flags-aconfig",
     package: "android.os",
+    exportable: true,
+    container: "system",
     srcs: ["core/java/android/os/*.aconfig"],
 }
 
@@ -326,6 +328,13 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+java_aconfig_library {
+    name: "android.os.flags-aconfig-java-export",
+    aconfig_declarations: "android.os.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+    mode: "exported",
+}
+
 // VirtualDeviceManager
 cc_aconfig_library {
     name: "android.companion.virtualdevice.flags-aconfig-cc",
diff --git a/Ravenwood.bp b/Ravenwood.bp
index c73e048..4791640 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -149,6 +149,7 @@
     installable: false,
     srcs: [":services.fakes-sources"],
     libs: [
+        "ravenwood-framework",
         "services.core.ravenwood",
     ],
     jarjar_rules: ":ravenwood-services-jarjar-rules",
@@ -204,6 +205,7 @@
         // Provide runtime versions of utils linked in below
         "junit",
         "truth",
+        "ravenwood-framework",
         "ravenwood-junit-impl",
         "mockito-ravenwood-prebuilt",
         "inline-mockito-ravenwood-prebuilt",
@@ -218,6 +220,7 @@
     libs: [
         "junit",
         "truth",
+        "ravenwood-framework",
         "ravenwood-junit",
         "mockito-ravenwood-prebuilt",
         "inline-mockito-ravenwood-prebuilt",
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java
index d14e93e..80a9c06 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java
@@ -27,8 +27,8 @@
 import android.perftests.utils.BitmapUtils;
 import android.perftests.utils.PerfStatusReporter;
 import android.perftests.utils.PerfTestActivity;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
diff --git a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java
index aa47e0a..80cd86c 100644
--- a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java
index 97ab6c7..2f6c378 100644
--- a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java
index bb452d3..d17add7 100644
--- a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java
index ff6d46f..3a57db8 100644
--- a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java
index e0c12dd..3fb3bc8 100644
--- a/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java
index 04ef09e4..2a1b5d1 100644
--- a/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java
index 4ae88b8..5f599ea 100644
--- a/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Assert;
diff --git a/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
index 5e73916..ea24984 100644
--- a/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java
index 3ebaa4c..82247dc 100644
--- a/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java
index da94ae1..0bebf04 100644
--- a/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java
index 9446d99c..55c1027 100644
--- a/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java
index be2a7e9..da60a77 100644
--- a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java
index ca99779..6d9d0c9 100644
--- a/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java
index 8496fbe..09b0977 100644
--- a/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java
index bb79424..ba21ed3 100644
--- a/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java
index 05a3e12..293752e 100644
--- a/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java
index 65a2fdb..528b751 100644
--- a/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java
index 4f5c54d..1f301ac 100644
--- a/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java
index 08ad926..4268325 100644
--- a/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java
index 20f1309..6363e9c 100644
--- a/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java
index 7e71976..cb3d3ac 100644
--- a/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java
index b1b594d..5be8ee6 100644
--- a/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java
index 412cb5a..a37b89d 100644
--- a/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java
@@ -18,9 +18,9 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Xml;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import libcore.util.XmlObjectFactory;
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
index 3a45d40..ed669be 100644
--- a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java
index 2e89518..d239a05 100644
--- a/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java
index d38d519..487295c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java
index cc56868..adc5d8c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java
index 662694b..286d703 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java
index 2c0473e..d646202 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java
index 6a2ce58..b887f40 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java
index b7b7e83..e4eaf12 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java
index 9ac36d0..cb2438e 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java
index 5dd9d6e..9ee927c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java
index 0a59899..e4a4db7 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java
index 8da13a9..858c101 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java
index 048c50f..a2fb7d7 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
index b753006..2047444 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java
@@ -18,8 +18,8 @@
 import android.icu.lang.UCharacter;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java
index 1d33fcb..4ce8b41 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java
index 35730ec..6a7ec1a 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java
index 42b0588..238c028 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java
index 6728e73..7e55660 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java
index 69197c3..100798a 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java
index 4dba139..b6784a8 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java
index f3eddab..52f9873 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java
index 2bf0418..6105420 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java
@@ -17,8 +17,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java
index c3320a4..fae74a5 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java
index 7c52ac4..2915363 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java
index d133359..dd7e5cc 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java
@@ -18,15 +18,14 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.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;
 
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java
index 38904af..e034a47 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java
index 8391203..fe1b599 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
index 7712aee..ecbfc71 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java
index 783136a..0c14d64 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java
index a995f5c..7d7d83b 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java
index 94c4f08..08dda53 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java
index c60930f..a09ad80 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java
index abcc972..be22814 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java
index c9f0616..4337c90 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java
index 78f744c..1b6c502 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java
index 5129fcb..0aa854e 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java
index 80c4487..9b3d7a0 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java
index c9b0cbe..1a9e19a 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java
index 4c2d7fb..a8a704c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java
index 2dc947a..6da9666 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java
index d9d4bb5..060d18f 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java
index dae185e..7cb3b22 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java
index 5ff2b22..272b45a 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java
index 48450b4..c3a0966 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java
index 21ccba5..2ac56be 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java
index f7bcf12..7ad0141 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java
index d8bff4c..c7b6cb5 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java
index 2542df9..44e5f22 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java
index b06662c..6e00b1083 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
index 694d609..5a9b5c3 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import libcore.java.security.TestKeyStore;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
index bdbbcb0..6d48cf2 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
index 5ad62de..8641629 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
index 1ec22d2..afd1191 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
index a9a0788..6c26133 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
@@ -17,7 +17,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
index c25b0ce..274b51f 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
index eeccb5b..b4c427b 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
index 10fa8b9..2235cc5 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
index 6854c0d..9ab5000 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import junit.framework.Assert;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
index 79ff646..b1e749c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
index 8dbf9f5..9e57591 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
index 36db014..a80514c 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
index 5b4423a..78ae395 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
index 4d5c792..73911c7 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
index 2bb25ac..1539271 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
index c004d95..0d5e62b 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
index 15516fc..ecdf809 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
index f256555..2b2a6b5 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
index 8274512..6eb8fcc 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
index ae1e8bc..288c646 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
@@ -18,7 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java
index e7bb8f8..003c957 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java
index 5bac46a..4f21618 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java
index 1005a70..210014a 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java
index 5224ad3..22c6827 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java
index 06696ef..5b39109 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java
index a784c52..883e8a7 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java
index 4ce0078..50bc85c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java
index 587e201..13fa2bf 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java
index e06b534..85c9bae9 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java
index 0fd16a0..2b8f430 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java
index 7ad42d0..246fa43 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java
index 76e1f47..d12ffae 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java
index b4b7840..5ced115 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java
index 09ed167..b955d50 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java
index 920d2e4..601ff34 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java
index 55ed789..0e567f9 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java
index ea3057b..6be2870 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java
index 20558aa9..84c186b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java
index d7b1d29..b093234 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java
index d138dc9..0d2037b4 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java
index 36153f2..ee31973 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java
index bf4fbc4..0571fef 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java
index d3c1b36..f619dab 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java
index 90e69a1..fc443fa 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java
index 96bc104..bf3d58b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java
index 2679494..1f4bc31 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java
index 170dce7..2085552 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java
index 11d12db..d9c7d7b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java
index bd2a600..acd2533 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java
index 99a09cd..de9944a 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java
index db83606..a863929 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java
index 4a8f924..4999b9b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java
index 4e4a9ee..ee80a6f 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java
index 3e7de1d..ec29f7a 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java
index 67d53b3..ee6a669 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java
index 470a1ce..1702b84 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java
index 8a982c2..514ddb9 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java
index 2c17a69..fbcee69 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java
index 099b1f4..2c56588 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java
index 7f6b4b8..8fce69e 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java
index 8592d30..ef530607 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java
index 539bd2a..64c0898 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java
index a36a7b6..939100c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java
index 90d2a70..728b199 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java
index 4e5fcf3..bf5ef99 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java
index fd0abf8..d15705e 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java
index 9272b11..222a60d 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java
index a896d0a..7436476 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java
index 671b0a3..cca97f4 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java
index 1eb3f92..170ee73 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java
index f23d5e2..184f796 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java
index 1613798..7e75c44 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java
index 14f1c00..39c386b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java
index 8327caf..04ab531 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java
index 6c211fb..b71351f 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java
index d02cd73..e3955c0 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java
index 0777586..adf05a6 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java
index 24a949f..4d657d9 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java
index 4b94bbe..dc64174 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java
index 1784c05..25d5631 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java
index f85d3ee..de2d548 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java
index 81f6779..36544c6 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java
index 9436fad..fb36d0c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java
index 9ebc458..4194b12 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java
index ea159a1..355c6e8 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java
index a42ec7e..401079d 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java
index 6f1007e5..322dcbf 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java
index 6a73818..c982814 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java
index e9a365b..0b1cb32 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java
index fc9191c..4737072 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java
index 5919a1d..204cd70 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java
index 313e580..b3ffed7 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java
index 9c8b3ae..d0ab8de 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java
index ea618cc..b378b68 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java
index df6f470..c7c66fe 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java
index 63fd740..98d6bd7 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java
index a96031e..206358f 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java
index 3bc25fb..0532e73 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java
index 7ffdf11..f192d71 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java
index cc7f3be..0a8909c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java
index 8d54c00..bfcb0f4 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java
index 22e92dd..c6b0509 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java
index 08ddc8b..45a01ed 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java
index 429e090..3047281 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java
index d5b31f6..6f1f1a0 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java
index 8667aaa..c4d279f 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java
index aa20246..c4f6005 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java
index 9e0210f..a6858c2 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java
index d489168..a994cbe 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java
index b06d7ef..65412ec 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java
index 8446937..573b0ff 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java
index 34540a3..fe3c0fc 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java
index c79b513..f398899 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java
index 028130d..7493120 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java
index 06a5a8c..5e73269 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java
index 78eefc8..9a217d1 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java
index cd1bd48..1ce2270 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java
index 6c0740c..ed84528 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java
index b95f24b..aeb9640 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java
index b03cf82..8959a0c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java
index c98c092..4007722 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java
index 625cfc7..7323158 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java
index 58319b3..f4119c2 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java
index f741542..9b9c261 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java
index 87f6a78..f125384 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java
index 610345f..2ad605d 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java
index 519d4fd..5ef3bf0 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java
index 322cf63..0c4ed66 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java
index f8ccbad..db6bd24 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java
index 16f1059..d2b0bf7 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java
index c7084fe..3cd5ae6 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java
index 9d526b8..6ddfc25 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java
index 8372f6c..375f0bc 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java
index 87e47e7..7e2492a 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java
index aa2e104..190118c 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java
index ebaa080..484ba1b 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java
index d90356a..80e4e15 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java
index 6db995a..fa26c59 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java
index ecea19e..16bf2a20 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java
index ab86284..e1716de 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java
index 23a33f5..dc6f2ad 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java
index 270b5ad..d1096c6 100644
--- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java
@@ -18,8 +18,8 @@
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Rule;
diff --git a/apex/jobscheduler/service/aconfig/alarm.aconfig b/apex/jobscheduler/service/aconfig/alarm.aconfig
index 3b9b4e7..bb0f3cb 100644
--- a/apex/jobscheduler/service/aconfig/alarm.aconfig
+++ b/apex/jobscheduler/service/aconfig/alarm.aconfig
@@ -9,3 +9,10 @@
       purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "start_user_before_scheduled_alarms"
+    namespace: "multiuser"
+    description: "Persist list of users with alarms scheduled and wakeup stopped users before alarms are due"
+    bug: "314907186"
+}
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index 6b1c7e8..15109d9 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -144,7 +144,7 @@
               "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
           .Build();
   ASSERT_TRUE(overlay);
-  TemporaryFile tf;
+  TempFrroFile tf;
   std::ofstream out(tf.path);
   ASSERT_TRUE((*overlay).ToBinaryStream(out));
   out.close();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index a384305..c85619c 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -274,7 +274,7 @@
                   .Build();
 
   ASSERT_TRUE(frro);
-  TemporaryFile tf;
+  TempFrroFile tf;
   std::ofstream out(tf.path);
   ASSERT_TRUE((*frro).ToBinaryStream(out));
   out.close();
@@ -467,9 +467,9 @@
 TEST(IdmapTests, IdmapHeaderIsUpToDate) {
   fclose(stderr);  // silence expected warnings from libandroidfw
 
-  const std::string target_apk_path = kIdmapRawTargetPath;
-  const std::string overlay_apk_path = kIdmapRawOverlayPath;
-  const std::string overlay_name = kIdmapRawOverlayName;
+  const std::string target_apk_path {kIdmapRawTargetPath};
+  const std::string overlay_apk_path {kIdmapRawOverlayPath};
+  const std::string overlay_name {kIdmapRawOverlayName};
   const PolicyBitmask policies = kIdmapRawDataPolicies;
   const uint32_t target_crc = kIdmapRawDataTargetCrc;
   const uint32_t overlay_crc = kIdmapRawOverlayCrc;
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index db44c23..1d22553 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -217,7 +217,7 @@
                   .Build();
 
   ASSERT_TRUE(frro);
-  TemporaryFile tf;
+  TempFrroFile tf;
   std::ofstream out(tf.path);
   ASSERT_TRUE((*frro).ToBinaryStream(out));
   out.close();
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index cdc0b8f..bf01c32 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -17,11 +17,15 @@
 #ifndef IDMAP2_TESTS_TESTHELPERS_H_
 #define IDMAP2_TESTS_TESTHELPERS_H_
 
+#include <stdio.h>
 #include <string>
+#include <string_view>
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
+#include "android-base/file.h"
+
 namespace android::idmap2 {
 
 const unsigned char kIdmapRawData[] = {
@@ -197,12 +201,23 @@
 const unsigned int kIdmapRawDataTargetCrc = 0x1234;
 const unsigned int kIdmapRawOverlayCrc = 0x5678;
 const unsigned int kIdmapRawDataPolicies = 0x11;
-inline const std::string kIdmapRawTargetPath = "targetX.apk";
-inline const std::string kIdmapRawOverlayPath = "overlayX.apk";
-inline const std::string kIdmapRawOverlayName = "OverlayName";
+inline const std::string_view kIdmapRawTargetPath = "targetX.apk";
+inline const std::string_view kIdmapRawOverlayPath = "overlayX.apk";
+inline const std::string_view kIdmapRawOverlayName = "OverlayName";
 
 std::string GetTestDataPath();
 
+class TempFrroFile : public TemporaryFile {
+public:
+  TempFrroFile() {
+    std::string new_path = path;
+    new_path += ".frro";
+    ::rename(path, new_path.c_str());
+    const auto new_len = new_path.copy(path, sizeof(path) - 1);
+    path[new_len] = '\0';
+  }
+};
+
 class Idmap2Tests : public testing::Test {
  protected:
   void SetUp() override {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1718452..2922dd9 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -15316,12 +15316,12 @@
     method @Deprecated public boolean getDataEnabled(int);
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion(int);
-    method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyAssistancePackage();
+    method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyAssistancePackageName();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
-    method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @Nullable @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID}) public android.telephony.CellIdentity getLastKnownCellIdentity();
+    method @FlaggedApi("com.android.server.telecom.flags.get_last_known_cell_identity") @Nullable @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID}) public android.telephony.CellIdentity getLastKnownCellIdentity();
     method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
     method public int getMaxNumberOfSimultaneouslyActiveSims();
     method public static long getMaxNumberVerificationTimeoutMillis();
diff --git a/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java b/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java
index cac1dc4..f1df336 100644
--- a/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java
+++ b/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java
@@ -25,9 +25,11 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.Flags;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FunctionalUtils;
 
 import java.io.IOException;
@@ -36,24 +38,46 @@
 
 /**
  * Default implementation of {@link BrailleDisplayController}.
+ *
+ * @hide
  */
 // BrailleDisplayControllerImpl is not an API, but it implements BrailleDisplayController APIs.
 // This @FlaggedApi annotation tells the linter that this method delegates API checks to its
 // callers.
 @FlaggedApi(Flags.FLAG_BRAILLE_DISPLAY_HID)
-final class BrailleDisplayControllerImpl implements BrailleDisplayController {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public final class BrailleDisplayControllerImpl implements BrailleDisplayController {
 
     private final AccessibilityService mAccessibilityService;
     private final Object mLock;
+    private final boolean mIsHidrawSupported;
 
     private IBrailleDisplayConnection mBrailleDisplayConnection;
     private Executor mCallbackExecutor;
     private BrailleDisplayCallback mCallback;
 
+    /**
+     * Read-only property that returns whether HIDRAW access is supported on this device.
+     *
+     * <p>Defaults to true.
+     *
+     * <p>Device manufacturers without HIDRAW kernel support can set this to false in
+     * the device's product makefile.
+     */
+    private static final boolean IS_HIDRAW_SUPPORTED = SystemProperties.getBoolean(
+            "ro.accessibility.support_hidraw", true);
+
     BrailleDisplayControllerImpl(AccessibilityService accessibilityService,
             Object lock) {
+        this(accessibilityService, lock, IS_HIDRAW_SUPPORTED);
+    }
+
+    @VisibleForTesting
+    public BrailleDisplayControllerImpl(AccessibilityService accessibilityService,
+            Object lock, boolean isHidrawSupported) {
         mAccessibilityService = accessibilityService;
         mLock = lock;
+        mIsHidrawSupported = isHidrawSupported;
     }
 
     @Override
@@ -113,6 +137,11 @@
                     createConnection,
             @NonNull Executor callbackExecutor, @NonNull BrailleDisplayCallback callback) {
         BrailleDisplayController.checkApiFlagIsEnabled();
+        if (!mIsHidrawSupported) {
+            callbackExecutor.execute(() -> callback.onConnectionFailed(
+                    BrailleDisplayCallback.FLAG_ERROR_CANNOT_ACCESS));
+            return;
+        }
         if (isConnected()) {
             throw new IllegalStateException(
                     "This service already has a connected Braille display");
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 083705b..b25ebf6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -14071,7 +14071,7 @@
     public void setAuditLogEnabled(boolean enabled) {
         throwIfParentInstance("setAuditLogEnabled");
         try {
-            mService.setAuditLogEnabled(mContext.getPackageName(), true);
+            mService.setAuditLogEnabled(mContext.getPackageName(), enabled);
         } catch (RemoteException re) {
             re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 10954ab..e1a6913 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -149,3 +149,10 @@
   description: "Allow to query whether MTE is enabled or not to check for compliance for enterprise policy"
   bug: "322777918"
 }
+
+flag {
+  name: "esim_management_ux_enabled"
+  namespace: "enterprise"
+  description: "Enable UX changes for esim management"
+  bug: "295301164"
+}
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 48ea846..6317725 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -40,6 +40,7 @@
 public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
 
     private Configuration mConfiguration;
+    private ActivityWindowInfo mActivityWindowInfo;
 
     @Override
     public void preExecute(@NonNull ClientTransactionHandler client) {
@@ -55,8 +56,7 @@
         // TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
         client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY,
-                // TODO(b/287582673): add ActivityWindowInfo
-                new ActivityWindowInfo());
+                mActivityWindowInfo);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
@@ -73,7 +73,7 @@
     /** Obtain an instance initialized with provided params. */
     @NonNull
     public static ActivityConfigurationChangeItem obtain(@NonNull IBinder activityToken,
-            @NonNull Configuration config) {
+            @NonNull Configuration config, @NonNull ActivityWindowInfo activityWindowInfo) {
         ActivityConfigurationChangeItem instance =
                 ObjectPool.obtain(ActivityConfigurationChangeItem.class);
         if (instance == null) {
@@ -81,6 +81,7 @@
         }
         instance.setActivityToken(activityToken);
         instance.mConfiguration = new Configuration(config);
+        instance.mActivityWindowInfo = new ActivityWindowInfo(activityWindowInfo);
 
         return instance;
     }
@@ -89,6 +90,7 @@
     public void recycle() {
         super.recycle();
         mConfiguration = null;
+        mActivityWindowInfo = null;
         ObjectPool.recycle(this);
     }
 
@@ -100,12 +102,14 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         super.writeToParcel(dest, flags);
         dest.writeTypedObject(mConfiguration, flags);
+        dest.writeTypedObject(mActivityWindowInfo, flags);
     }
 
     /** Read from Parcel. */
     private ActivityConfigurationChangeItem(@NonNull Parcel in) {
         super(in);
         mConfiguration = in.readTypedObject(Configuration.CREATOR);
+        mActivityWindowInfo = in.readTypedObject(ActivityWindowInfo.CREATOR);
     }
 
     public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
@@ -128,7 +132,8 @@
             return false;
         }
         final ActivityConfigurationChangeItem other = (ActivityConfigurationChangeItem) o;
-        return Objects.equals(mConfiguration, other.mConfiguration);
+        return Objects.equals(mConfiguration, other.mConfiguration)
+                && Objects.equals(mActivityWindowInfo, other.mActivityWindowInfo);
     }
 
     @Override
@@ -136,12 +141,14 @@
         int result = 17;
         result = 31 * result + super.hashCode();
         result = 31 * result + Objects.hashCode(mConfiguration);
+        result = 31 * result + Objects.hashCode(mActivityWindowInfo);
         return result;
     }
 
     @Override
     public String toString() {
         return "ActivityConfigurationChange{" + super.toString()
-                + ",config=" + mConfiguration + "}";
+                + ",config=" + mConfiguration
+                + ",activityWindowInfo=" + mActivityWindowInfo + "}";
     }
 }
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index ecffe9e..faa2c70 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -392,8 +392,6 @@
             return;
         }
 
-        Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than "
-                + threshold + "; truncating");
         try {
             executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null);
             mConfiguration.shouldTruncateWalFile = false;
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 5e523c0..78c8954 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -377,8 +377,7 @@
                     if (writable) {
                         throw ex;
                     }
-                    Log.e(TAG, "Couldn't open " + mName
-                            + " for writing (will try read-only):", ex);
+                    Log.e(TAG, "Couldn't open database for writing (will try read-only):", ex);
                     params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
                     db = SQLiteDatabase.openDatabase(filePath, params);
                 }
@@ -425,11 +424,6 @@
             }
 
             onOpen(db);
-
-            if (db.isReadOnly()) {
-                Log.w(TAG, "Opened " + mName + " in read-only mode");
-            }
-
             mDatabase = db;
             return db;
         } finally {
diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl
index 65e498e..8b1577c 100644
--- a/core/java/android/os/IVibratorManagerService.aidl
+++ b/core/java/android/os/IVibratorManagerService.aidl
@@ -41,5 +41,5 @@
     // There is no order guarantee with respect to the two-way APIs above like
     // vibrate/isVibrating/cancel.
     oneway void performHapticFeedback(int uid, int deviceId, String opPkg, int constant,
-            boolean always, String reason);
+            boolean always, String reason, boolean fromIme);
 }
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 3950c25..2fe115f 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -623,14 +623,14 @@
                 // Message is to be inserted at tail or middle of queue. Usually we don't have to
                 // wake up the event queue unless there is a barrier at the head of the queue and
                 // the message is the earliest asynchronous message in the queue.
-                //
+                needWake = mBlocked && p.target == null && msg.isAsynchronous();
+
                 // For readability, we split this portion of the function into two blocks based on
                 // whether tail tracking is enabled. This has a minor implication for the case
                 // where tail tracking is disabled. See the comment below.
                 if (Flags.messageQueueTailTracking()) {
-                    needWake = mBlocked && p.target == null && msg.isAsynchronous()
-                        && mAsyncMessageCount == 0;
                     if (when >= mLast.when) {
+                        needWake = needWake && mAsyncMessageCount == 0;
                         msg.next = null;
                         mLast.next = msg;
                         mLast = msg;
@@ -643,6 +643,9 @@
                             if (p == null || when < p.when) {
                                 break;
                             }
+                            if (needWake && p.isAsynchronous()) {
+                                needWake = false;
+                            }
                         }
                         if (p == null) {
                             /* Inserting at tail of queue */
@@ -652,7 +655,6 @@
                         prev.next = msg;
                     }
                 } else {
-                    needWake = mBlocked && p.target == null && msg.isAsynchronous();
                     Message prev;
                     for (;;) {
                         prev = p;
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 04c257b..2a62c24 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -206,12 +206,13 @@
     }
 
     @Override
-    public void performHapticFeedback(int constant, boolean always, String reason) {
+    public void performHapticFeedback(
+            int constant, boolean always, String reason, boolean fromIme) {
         if (mVibratorManager == null) {
             Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager.");
             return;
         }
-        mVibratorManager.performHapticFeedback(constant, always, reason);
+        mVibratorManager.performHapticFeedback(constant, always, reason, fromIme);
     }
 
     @Override
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index 8e83923..c80bcac 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -147,14 +147,15 @@
     }
 
     @Override
-    public void performHapticFeedback(int constant, boolean always, String reason) {
+    public void performHapticFeedback(int constant, boolean always, String reason,
+            boolean fromIme) {
         if (mService == null) {
             Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service.");
             return;
         }
         try {
             mService.performHapticFeedback(
-                    mUid, mContext.getDeviceId(), mPackageName, constant, always, reason);
+                    mUid, mContext.getDeviceId(), mPackageName, constant, always, reason, fromIme);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to perform haptic feedback.", e);
         }
@@ -244,8 +245,9 @@
         }
 
         @Override
-        public void performHapticFeedback(int effectId, boolean always, String reason) {
-            SystemVibratorManager.this.performHapticFeedback(effectId, always, reason);
+        public void performHapticFeedback(int effectId, boolean always, String reason,
+                boolean fromIme) {
+            SystemVibratorManager.this.performHapticFeedback(effectId, always, reason, fromIme);
         }
 
         @Override
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 46705a3..9df5b85 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -289,6 +289,15 @@
     }
 
     /**
+     * Return the original {@link AudioAttributes} used to create the vibration attributes.
+     * @hide
+     */
+    @AudioAttributes.AttributeUsage
+    public int getOriginalAudioUsage() {
+        return mOriginalAudioUsage;
+    }
+
+    /**
      * Return the flags.
      * @return a combined mask of all flags
      */
@@ -405,8 +414,8 @@
         return "VibrationAttributes{"
                 + "mUsage=" + usageToString()
                 + ", mAudioUsage= " + AudioAttributes.usageToString(mOriginalAudioUsage)
-                + ", mFlags=" + mFlags
                 + ", mCategory=" + categoryToString()
+                + ", mFlags=" + mFlags
                 + '}';
     }
 
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 2fc2414..4b2d4eb 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -534,10 +534,12 @@
      *          {@code false} if the vibration for the haptic feedback should respect the applicable
      *          vibration intensity settings.
      * @param reason the reason for this haptic feedback.
+     * @param fromIme the haptic feedback is performed from an IME.
      *
      * @hide
      */
-    public void performHapticFeedback(int constant, boolean always, String reason) {
+    public void performHapticFeedback(int constant, boolean always, String reason,
+            boolean fromIme) {
         Log.w(TAG, "performHapticFeedback is not supported");
     }
 
diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java
index e0b6a9f..513c4bd 100644
--- a/core/java/android/os/VibratorManager.java
+++ b/core/java/android/os/VibratorManager.java
@@ -146,9 +146,11 @@
      *          vibration intensity settings applicable to the corresponding vibration.
      *          {@code false} otherwise.
      * @param reason the reason for this haptic feedback.
+     * @param fromIme the haptic feedback is performed from an IME.
      * @hide
      */
-    public void performHapticFeedback(int constant, boolean always, String reason) {
+    public void performHapticFeedback(int constant, boolean always, String reason,
+            boolean fromIme) {
         Log.w(TAG, "performHapticFeedback is not supported");
     }
 
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index abfa4e3..d9400ac 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.os"
+container: "system"
 
 flag {
     name: "android_os_build_vanilla_ice_cream"
@@ -40,6 +41,7 @@
     namespace: "profile_experiences"
     description: "Guards a new Private Profile type in UserManager - everything from its setup to config to deletion."
     bug: "299069460"
+    is_exported: true
 }
 
 flag {
diff --git a/core/java/android/os/vibrator/VibrationConfig.java b/core/java/android/os/vibrator/VibrationConfig.java
index bcdb982..a14a2c7 100644
--- a/core/java/android/os/vibrator/VibrationConfig.java
+++ b/core/java/android/os/vibrator/VibrationConfig.java
@@ -224,17 +224,19 @@
     @Override
     public String toString() {
         return "VibrationConfig{"
-                + "mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude
+                + "mIgnoreVibrationsOnWirelessCharger=" + mIgnoreVibrationsOnWirelessCharger
+                + ", mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude
                 + ", mRampStepDurationMs=" + mRampStepDurationMs
                 + ", mRampDownDurationMs=" + mRampDownDurationMs
+                + ", mRequestVibrationParamsForUsages="
+                + Arrays.toString(getRequestVibrationParamsForUsagesNames())
+                + ", mRequestVibrationParamsTimeoutMs=" + mRequestVibrationParamsTimeoutMs
                 + ", mDefaultAlarmIntensity=" + mDefaultAlarmVibrationIntensity
                 + ", mDefaultHapticFeedbackIntensity=" + mDefaultHapticFeedbackIntensity
                 + ", mDefaultMediaIntensity=" + mDefaultMediaVibrationIntensity
                 + ", mDefaultNotificationIntensity=" + mDefaultNotificationVibrationIntensity
                 + ", mDefaultRingIntensity=" + mDefaultRingVibrationIntensity
-                + ", mRequestVibrationParamsTimeoutMs=" + mRequestVibrationParamsTimeoutMs
-                + ", mRequestVibrationParamsForUsages=" + Arrays.toString(
-                getRequestVibrationParamsForUsagesNames())
+                + ", mDefaultKeyboardVibrationEnabled=" + mDefaultKeyboardVibrationEnabled
                 + "}";
     }
 
@@ -246,9 +248,13 @@
     public void dumpWithoutDefaultSettings(IndentingPrintWriter pw) {
         pw.println("VibrationConfig:");
         pw.increaseIndent();
+        pw.println("ignoreVibrationsOnWirelessCharger = " + mIgnoreVibrationsOnWirelessCharger);
         pw.println("hapticChannelMaxAmplitude = " + mHapticChannelMaxVibrationAmplitude);
         pw.println("rampStepDurationMs = " + mRampStepDurationMs);
         pw.println("rampDownDurationMs = " + mRampDownDurationMs);
+        pw.println("requestVibrationParamsForUsages = "
+                + Arrays.toString(getRequestVibrationParamsForUsagesNames()));
+        pw.println("requestVibrationParamsTimeoutMs = " + mRequestVibrationParamsTimeoutMs);
         pw.decreaseIndent();
     }
 
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 8495f37..fa9f03d 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -247,8 +247,6 @@
 
     private final LegacyPermissionManager mLegacyPermissionManager;
 
-    private final VirtualDeviceManager mVirtualDeviceManager;
-
     private final ArrayMap<PackageManager.OnPermissionsChangedListener,
             IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>();
     private PermissionUsageHelper mUsageHelper;
@@ -269,7 +267,6 @@
         mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
                 "permissionmgr"));
         mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class);
-        mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
     }
 
     /**
@@ -1918,14 +1915,18 @@
         if (deviceId == Context.DEVICE_ID_DEFAULT) {
             persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
         } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) {
-            VirtualDevice virtualDevice = mVirtualDeviceManager.getVirtualDevice(deviceId);
-            if (virtualDevice == null) {
-                Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId);
-                return null;
-            }
-            persistentDeviceId = virtualDevice.getPersistentDeviceId();
-            if (persistentDeviceId == null) {
-                Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId);
+            VirtualDeviceManager virtualDeviceManager = mContext.getSystemService(
+                    VirtualDeviceManager.class);
+            if (virtualDeviceManager != null) {
+                VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId);
+                if (virtualDevice == null) {
+                    Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId);
+                    return null;
+                }
+                persistentDeviceId = virtualDevice.getPersistentDeviceId();
+                if (persistentDeviceId == null) {
+                    Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId);
+                }
             }
         } else {
             Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId
diff --git a/core/java/android/provider/E2eeContactKeysManager.java b/core/java/android/provider/E2eeContactKeysManager.java
index b694417..09c93e3 100644
--- a/core/java/android/provider/E2eeContactKeysManager.java
+++ b/core/java/android/provider/E2eeContactKeysManager.java
@@ -76,12 +76,14 @@
 public final class E2eeContactKeysManager {
     /**
      * The authority for the end-to-end encryption contact keys provider.
+     *
      * @hide
      */
     public static final String AUTHORITY = "com.android.contactkeys.contactkeysprovider";
 
     /**
      * A content:// style uri to the authority for the end-to-end encryption contact keys provider.
+     *
      * @hide
      */
     @NonNull
@@ -112,9 +114,9 @@
      * The inserted/updated end-to-end encryption contact key is owned by the caller app.
      *
      * @param lookupKey value that references the contact
-     * @param deviceId an app-specified identifier for the device
+     * @param deviceId  an app-specified identifier for the device
      * @param accountId an app-specified identifier for the account
-     * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes)
+     * @param keyValue  the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes)
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
     public void updateOrInsertE2eeContactKey(@NonNull String lookupKey,
@@ -138,9 +140,8 @@
      * accountId and inferred caller package name.
      *
      * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
+     * @param deviceId  an app-specified identifier for the device
      * @param accountId an app-specified identifier for the account
-     *
      * @return a {@link E2eeContactKey} object containing the contact key information,
      * or null if no contact key is found.
      */
@@ -170,7 +171,6 @@
      * The keys will be stripped of deviceId, timeUpdated and keyValue data.
      *
      * @param lookupKey the value that references the contact
-     *
      * @return a list of {@link E2eeContactKey} objects containing the contact key
      * information, or an empty list if no keys are found.
      */
@@ -199,7 +199,6 @@
      * the caller app.
      *
      * @param lookupKey the value that references the contact
-     *
      * @return a list of {@link E2eeContactKey} objects containing the end-to-end encryption
      * contact key information, or an empty list if no keys are found.
      */
@@ -227,11 +226,10 @@
      * Updates an end-to-end encryption contact key entry's local verification state that belongs
      * to the caller app.
      *
-     * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
+     * @param lookupKey              the value that references the contact
+     * @param deviceId               an app-specified identifier for the device
+     * @param accountId              an app-specified identifier for the account
      * @param localVerificationState the new local verification state
-     *
      * @return true if the entry was updated, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -257,14 +255,12 @@
      * Updates an end-to-end encryption contact key entry's local verification state that belongs
      * to the app identified by ownerPackageName.
      *
-     * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
-     * @param ownerPackageName the package name of the app that owns the key
+     * @param lookupKey              the value that references the contact
+     * @param deviceId               an app-specified identifier for the device
+     * @param accountId              an app-specified identifier for the account
+     * @param ownerPackageName       the package name of the app that owns the key
      * @param localVerificationState the new local verification state
-     *
      * @return true if the entry was updated, false otherwise.
-     *
      * @hide
      */
     @SystemApi
@@ -296,11 +292,10 @@
      * Updates an end-to-end encryption contact key entry's remote verification state that belongs
      * to the caller app.
      *
-     * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
+     * @param lookupKey               the value that references the contact
+     * @param deviceId                an app-specified identifier for the device
+     * @param accountId               an app-specified identifier for the account
      * @param remoteVerificationState the new remote verification state
-     *
      * @return true if the entry was updated, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -326,14 +321,12 @@
      * Updates an end-to-end encryption contact key entry's remote verification state that belongs
      * to the app identified by ownerPackageName.
      *
-     * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
-     * @param ownerPackageName the package name of the app that owns the key
+     * @param lookupKey               the value that references the contact
+     * @param deviceId                an app-specified identifier for the device
+     * @param accountId               an app-specified identifier for the account
+     * @param ownerPackageName        the package name of the app that owns the key
      * @param remoteVerificationState the new remote verification state
-     *
      * @return true if the entry was updated, false otherwise.
-     *
      * @hide
      */
     @SystemApi
@@ -374,9 +367,8 @@
      * Removes an end-to-end encryption contact key entry that belongs to the caller app.
      *
      * @param lookupKey the value that references the contact
-     * @param deviceId an app-specified identifier for the device
+     * @param deviceId  an app-specified identifier for the device
      * @param accountId an app-specified identifier for the account
-     *
      * @return true if the entry was removed, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -397,11 +389,10 @@
     /**
      * Inserts a new entry into the end-to-end encryption self keys table or updates one if it
      * already exists.
-
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
-     * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes)
      *
+     * @param deviceId  an app-specified identifier for the device
+     * @param accountId an app-specified identifier for the account
+     * @param keyValue  the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes)
      * @return true if the entry was added or updated, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -432,10 +423,9 @@
     /**
      * Updates an end-to-end encryption self key entry's remote verification state.
      *
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
+     * @param deviceId                an app-specified identifier for the device
+     * @param accountId               an app-specified identifier for the account
      * @param remoteVerificationState the new remote verification state
-     *
      * @return true if the entry was updated, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -459,13 +449,11 @@
      * Updates an end-to-end encryption self key entry's remote verification state that belongs to
      * the app identified by ownerPackageName.
      *
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
-     * @param ownerPackageName the package name of the app that owns the key
+     * @param deviceId                an app-specified identifier for the device
+     * @param accountId               an app-specified identifier for the account
+     * @param ownerPackageName        the package name of the app that owns the key
      * @param remoteVerificationState the new remote verification state
-     *
      * @return true if the entry was updated, false otherwise.
-     *
      * @hide
      */
     @SystemApi
@@ -502,9 +490,8 @@
      * Returns an end-to-end encryption self key entry given the deviceId and the inferred package
      * name of the caller.
      *
-     * @param deviceId an app-specified identifier for the device
+     * @param deviceId  an app-specified identifier for the device
      * @param accountId an app-specified identifier for the account
-     *
      * @return a {@link E2eeSelfKey} object containing the end-to-end encryption self key
      * information, or null if no self key is found.
      */
@@ -579,9 +566,9 @@
     /**
      * Removes an end-to-end encryption self key entry given the deviceId and the inferred
      * package name of the caller.
-     * @param deviceId an app-specified identifier for the device
-     * @param accountId an app-specified identifier for the account
      *
+     * @param deviceId  an app-specified identifier for the device
+     * @param accountId an app-specified identifier for the account
      * @return true if the entry was removed, false otherwise.
      */
     @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS)
@@ -608,6 +595,7 @@
 
     /**
      * Possible values of verification state.
+     *
      * @hide
      */
     @IntDef(prefix = {"VERIFICATION_STATE_"}, value = {
@@ -616,7 +604,8 @@
             VERIFICATION_STATE_VERIFIED
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface VerificationState {}
+    public @interface VerificationState {
+    }
 
     /**
      * Unverified state of a contact end to end encrypted key.
@@ -634,7 +623,8 @@
     /** @hide */
     public static final class E2eeContactKeys {
 
-        private E2eeContactKeys() {}
+        private E2eeContactKeys() {
+        }
 
         /**
          * <p>
@@ -808,34 +798,7 @@
     /**
      * A parcelable class encapsulating other users' end to end encrypted contact key.
      */
-    public static final class E2eeContactKey implements Parcelable {
-        /**
-         * An app-specified identifier for the device for which the end-to-end encryption
-         * contact key can be used.
-         */
-        private final String mDeviceId;
-
-        /**
-         * An app-specified identifier for the account for which the end-to-end encryption
-         * contact key can be used.
-         * Usually a phone number.
-         */
-        private final String mAccountId;
-
-        /**
-         * Owner application package name.
-         */
-        private final String mOwnerPackageName;
-
-        /**
-         * Timestamp at which the key was updated.
-         */
-        private final long mTimeUpdated;
-
-        /**
-         * The raw bytes for the key.
-         */
-        private final byte[] mKeyValue;
+    public static final class E2eeContactKey extends E2eeBaseKey implements Parcelable {
 
         /**
          * Describes the local verification state for the key, for instance QR-code based
@@ -844,12 +807,6 @@
         private final int mLocalVerificationState;
 
         /**
-         * Describes the remote verification state for the key, for instance through a key
-         * transparency server.
-         */
-        private final int mRemoteVerificationState;
-
-        /**
          * The display name for the contact.
          */
         private final String mDisplayName;
@@ -873,77 +830,15 @@
                 @VerificationState int remoteVerificationState,
                 @Nullable String displayName,
                 @Nullable String phoneNumber, @Nullable String emailAddress) {
-            this.mDeviceId = deviceId;
-            this.mAccountId = accountId;
-            this.mOwnerPackageName = ownerPackageName;
-            this.mTimeUpdated = timeUpdated;
-            this.mKeyValue = keyValue == null ? null : Arrays.copyOf(keyValue, keyValue.length);
+            super(deviceId, accountId, ownerPackageName, timeUpdated, keyValue,
+                    remoteVerificationState);
             this.mLocalVerificationState = localVerificationState;
-            this.mRemoteVerificationState = remoteVerificationState;
             this.mDisplayName = displayName;
             this.mPhoneNumber = phoneNumber;
             this.mEmailAddress = emailAddress;
         }
 
         /**
-         * Gets the app-specified identifier for the device for which the end-to-end encryption
-         * contact key can be used.
-         * Returns null if the app doesn't have the required visibility into
-         * the end-to-end encryption contact key.
-         *
-         * @return An app-specified identifier for the device.
-         */
-        @Nullable
-        public String getDeviceId() {
-            return mDeviceId;
-        }
-
-        /**
-         * Gets the app-specified identifier for the account for which the end-to-end encryption
-         * contact key can be used.
-         * Usually a phone number.
-         *
-         * @return An app-specified identifier for the account.
-         */
-        @NonNull
-        public String getAccountId() {
-            return mAccountId;
-        }
-
-        /**
-         * Gets the owner application package name.
-         *
-         * @return The owner application package name.
-         */
-        @NonNull
-        public String getOwnerPackageName() {
-            return mOwnerPackageName;
-        }
-
-        /**
-         * Gets the timestamp at which the key was updated. Returns -1 if the app doesn't have the
-         * required visibility into the end-to-end encryption contact key.
-         *
-         * @return The timestamp at which the key was updated in the System.currentTimeMillis()
-         * base.
-         */
-        public long getTimeUpdated() {
-            return mTimeUpdated;
-        }
-
-        /**
-         * Gets the raw bytes for the key.
-         * Returns null if the app doesn't have the required visibility into
-         * the end-to-end encryption contact key.
-         *
-         * @return A copy of the raw bytes for the key.
-         */
-        @Nullable
-        public byte[] getKeyValue() {
-            return mKeyValue == null ? null : Arrays.copyOf(mKeyValue, mKeyValue.length);
-        }
-
-        /**
          * Gets the local verification state for the key, for instance QR-code based verification.
          *
          * @return The local verification state for the key.
@@ -953,16 +848,6 @@
         }
 
         /**
-         * Gets the remote verification state for the key, for instance through a key transparency
-         * server.
-         *
-         * @return The remote verification state for the key.
-         */
-        public @VerificationState int getRemoteVerificationState() {
-            return mRemoteVerificationState;
-        }
-
-        /**
          * Gets the display name for the contact.
          *
          * @return The display name for the contact.
@@ -1079,122 +964,15 @@
     /**
      * A parcelable class encapsulating self end to end encrypted contact key.
      */
-    public static final class E2eeSelfKey implements Parcelable {
-        /**
-         * An app-specified identifier for the device for which the end-to-end encryption
-         * contact key can be used.
-         */
-        private final String mDeviceId;
-
-        /**
-         * An app-specified identifier for the account for which the end-to-end encryption
-         * contact key can be used.
-         * Usually a phone number.
-         */
-        private final String mAccountId;
-
-        /**
-         * Owner application package name.
-         */
-        private final String mOwnerPackageName;
-
-        /**
-         * Timestamp at which the key was updated.
-         */
-        private final long mTimeUpdated;
-
-        /**
-         * The raw bytes for the key.
-         */
-        private final byte[] mKeyValue;
-
-
-        /**
-         * Describes the remote verification state for the key, for instance through a key
-         * transparency server.
-         */
-        private final int mRemoteVerificationState;
-
+    public static final class E2eeSelfKey extends E2eeBaseKey implements Parcelable {
         /**
          * @hide
          */
         public E2eeSelfKey(@Nullable String deviceId, @NonNull String accountId,
                 @NonNull String ownerPackageName, long timeUpdated, @Nullable byte[] keyValue,
                 @VerificationState int remoteVerificationState) {
-            this.mDeviceId = deviceId;
-            this.mAccountId = accountId;
-            this.mOwnerPackageName = ownerPackageName;
-            this.mTimeUpdated = timeUpdated;
-            this.mKeyValue = keyValue == null ? null : Arrays.copyOf(keyValue, keyValue.length);
-            this.mRemoteVerificationState = remoteVerificationState;
-        }
-
-        /**
-         * Gets the app-specified identifier for the device for which the end-to-end encryption
-         * contact key can be used.
-         * Returns null if the app doesn't have the required visibility into
-         * the end-to-end encryption contact key.
-         *
-         * @return An app-specified identifier for the device.
-         */
-        @Nullable
-        public String getDeviceId() {
-            return mDeviceId;
-        }
-
-        /**
-         * Gets the app-specified identifier for the account for which the end-to-end encryption
-         * contact key can be used.
-         * Usually a phone number.
-         *
-         * @return An app-specified identifier for the device.
-         */
-        @NonNull
-        public String getAccountId() {
-            return mAccountId;
-        }
-
-        /**
-         * Gets the owner application package name.
-         *
-         * @return The owner application package name.
-         */
-        @NonNull
-        public String getOwnerPackageName() {
-            return mOwnerPackageName;
-        }
-
-        /**
-         * Gets the timestamp at which the key was updated. Returns -1 if the app doesn't have the
-         * required visibility into the end-to-end encryption contact key.
-         *
-         * @return The timestamp at which the key was updated in the System.currentTimeMillis()
-         * base.
-         */
-        public long getTimeUpdated() {
-            return mTimeUpdated;
-        }
-
-        /**
-         * Gets the raw bytes for the key.
-         * Returns null if the app doesn't have the required visibility into
-         * the end-to-end encryption contact key.
-         *
-         * @return A copy of the raw bytes for the key.
-         */
-        @Nullable
-        public byte[] getKeyValue() {
-            return mKeyValue == null ? null : Arrays.copyOf(mKeyValue, mKeyValue.length);
-        }
-
-        /**
-         * Gets the remote verification state for the key, for instance through a key transparency
-         * server.
-         *
-         * @return The remote verification state for the key.
-         */
-        public @VerificationState int getRemoteVerificationState() {
-            return mRemoteVerificationState;
+            super(deviceId, accountId, ownerPackageName, timeUpdated, keyValue,
+                    remoteVerificationState);
         }
 
         @Override
@@ -1266,4 +1044,122 @@
                     }
                 };
     }
+
+    /**
+     * An abstract class that's extended by self and contact key classes.
+     *
+     * @hide
+     */
+    abstract static class E2eeBaseKey {
+        /**
+         * An app-specified identifier for the device for which the key can be used.
+         */
+        protected final String mDeviceId;
+
+        /**
+         * An app-specified identifier for the account for which the key can be used.
+         * Usually a phone number.
+         */
+        protected final String mAccountId;
+
+        /**
+         * Owner application package name.
+         */
+        protected final String mOwnerPackageName;
+
+        /**
+         * Timestamp at which the key was updated.
+         */
+        protected final long mTimeUpdated;
+
+        /**
+         * The raw bytes for the key.
+         */
+        protected final byte[] mKeyValue;
+
+        /**
+         * Describes the remote verification state for the end-to-end encryption key, for instance
+         * through a key transparency server.
+         */
+        protected final int mRemoteVerificationState;
+
+        protected E2eeBaseKey(@Nullable String deviceId, @NonNull String accountId,
+                @NonNull String ownerPackageName, long timeUpdated, @Nullable byte[] keyValue,
+                @VerificationState int remoteVerificationState) {
+            this.mDeviceId = deviceId;
+            this.mAccountId = accountId;
+            this.mOwnerPackageName = ownerPackageName;
+            this.mTimeUpdated = timeUpdated;
+            this.mKeyValue = keyValue == null ? null : Arrays.copyOf(keyValue, keyValue.length);
+            this.mRemoteVerificationState = remoteVerificationState;
+        }
+
+        /**
+         * Gets the app-specified identifier for the device for which the end-to-end encryption
+         * key can be used.
+         * Returns null if the app doesn't have the required visibility into
+         * the end-to-end encryption key.
+         *
+         * @return An app-specified identifier for the device.
+         */
+        @Nullable
+        public String getDeviceId() {
+            return mDeviceId;
+        }
+
+        /**
+         * Gets the app-specified identifier for the account for which the end-to-end encryption
+         * key can be used.
+         * Usually a phone number.
+         *
+         * @return An app-specified identifier for the account.
+         */
+        @NonNull
+        public String getAccountId() {
+            return mAccountId;
+        }
+
+        /**
+         * Gets the owner application package name.
+         *
+         * @return The owner application package name.
+         */
+        @NonNull
+        public String getOwnerPackageName() {
+            return mOwnerPackageName;
+        }
+
+        /**
+         * Gets the timestamp at which the end-to-end encryption key was updated. Returns -1 if
+         * the app doesn't have the required visibility into the key.
+         *
+         * @return The timestamp at which the key was updated in the System.currentTimeMillis()
+         * base.
+         */
+        public long getTimeUpdated() {
+            return mTimeUpdated;
+        }
+
+        /**
+         * Gets the raw bytes for the end-to-end encryption key.
+         * Returns null if the app doesn't have the required visibility into
+         * the end-to-end encryption key.
+         *
+         * @return A copy of the raw bytes for the end-to-end encryption key.
+         */
+        @Nullable
+        public byte[] getKeyValue() {
+            return mKeyValue == null ? null : Arrays.copyOf(mKeyValue, mKeyValue.length);
+        }
+
+        /**
+         * Gets the remote verification state for the end-to-end encryption key, for instance
+         * through a key transparency server.
+         *
+         * @return The remote verification state for the end-to-end encryption key.
+         */
+        public @VerificationState int getRemoteVerificationState() {
+            return mRemoteVerificationState;
+        }
+    }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 20b4857..51585af 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -471,6 +471,21 @@
             "android.settings.ACCESSIBILITY_COLOR_MOTION_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow configuration of accessibility color contrast.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ACCESSIBILITY_COLOR_CONTRAST_SETTINGS =
+            "android.settings.ACCESSIBILITY_COLOR_CONTRAST_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of Reduce Bright Colors.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index b1bca96..cedba85 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -8,7 +8,7 @@
 }
 
 flag {
-    name: "perfetto_protolog"
+    name: "perfetto_protolog_tracing"
     namespace: "windowing_tools"
     description: "Migrate protolog to Perfetto"
     bug: "276432490"
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index d68a47c..e126836 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -148,13 +148,13 @@
             int seqId);
 
     @UnsupportedAppUsage
-    boolean performHapticFeedback(int effectId, boolean always);
+    boolean performHapticFeedback(int effectId, boolean always, boolean fromIme);
 
     /**
      * Called by attached views to perform predefined haptic feedback without requiring VIBRATE
      * permission.
      */
-    oneway void performHapticFeedbackAsync(int effectId, boolean always);
+    oneway void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme);
 
     /**
      * Initiate the drag operation itself
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index f5f4fd9..9099f98 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -428,13 +428,11 @@
 
     private BitmapDrawable getBitmapDrawableFromVectorDrawable(Resources resources,
             VectorDrawable vectorDrawable) {
-        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
-                vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-        // BitmapDrawables and Bitmap have a default density of DisplayMetrics.DENSITY_DEVICE,
-        // (which is deprecated in favor of DENSITY_DEVICE_STABLE/resources.densityDpi). In
-        // rare cases when device density differs from the resource density, the bitmap will
-        // scale as the BitmapDrawable is created. Avoid by explicitly setting density here.
-        bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
+        // Ensure we pass the display metrics into the Bitmap constructor so that it is initialized
+        // with the correct density.
+        Bitmap bitmap = Bitmap.createBitmap(resources.getDisplayMetrics(),
+                vectorDrawable.getIntrinsicWidth(),
+                vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888, true /* hasAlpha */);
         Canvas canvas = new Canvas(bitmap);
         vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
         vectorDrawable.draw(canvas);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 042af1f..3478286 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -25,6 +25,7 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
 import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS;
 import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
@@ -16815,10 +16816,15 @@
             mAttachInfo.mViewRootImpl.getWindowVisibleDisplayFrame(outRect);
             return;
         }
-        // The view is not attached to a display so we don't have a context.
-        // Make a best guess about the display size.
-        Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
-        d.getRectSize(outRect);
+        // TODO (b/327559224): Refine the behavior to better reflect the window environment with API
+        //  doc updates.
+        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+        final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
+        final Insets insets = metrics.getWindowInsets().getInsets(
+                WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+        outRect.set(metrics.getBounds());
+        outRect.inset(insets);
+        outRect.offsetTo(0, 0);
     }
 
     /**
@@ -28371,15 +28377,19 @@
         }
 
         final boolean always = (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0;
+        boolean fromIme = false;
+        if (mAttachInfo.mViewRootImpl != null) {
+            fromIme = mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
+        }
         if (Flags.useVibratorHapticFeedback()) {
             if (!mAttachInfo.canPerformHapticFeedback()) {
                 return false;
             }
             getSystemVibrator().performHapticFeedback(
-                    feedbackConstant, always, "View#performHapticFeedback");
+                    feedbackConstant, always, "View#performHapticFeedback", fromIme);
             return true;
         }
-        return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always);
+        return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always, fromIme);
     }
 
     private Vibrator getSystemVibrator() {
@@ -31422,7 +31432,7 @@
 
         interface Callbacks {
             void playSoundEffect(int effectId);
-            boolean performHapticFeedback(int effectId, boolean always);
+            boolean performHapticFeedback(int effectId, boolean always, boolean fromIme);
         }
 
         /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 333cbb3..708751a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -9201,18 +9201,18 @@
      * {@inheritDoc}
      */
     @Override
-    public boolean performHapticFeedback(int effectId, boolean always) {
+    public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
         if ((mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
             return false;
         }
 
         try {
             if (USE_ASYNC_PERFORM_HAPTIC_FEEDBACK) {
-                mWindowSession.performHapticFeedbackAsync(effectId, always);
+                mWindowSession.performHapticFeedbackAsync(effectId, always, fromIme);
                 return true;
             } else {
                 // Original blocking binder call path.
-                return mWindowSession.performHapticFeedback(effectId, always);
+                return mWindowSession.performHapticFeedback(effectId, always, fromIme);
             }
         } catch (RemoteException e) {
             return false;
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 2b2c507..22d8ed9 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -479,13 +479,13 @@
     }
 
     @Override
-    public boolean performHapticFeedback(int effectId, boolean always) {
+    public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
         return false;
     }
 
     @Override
-    public void performHapticFeedbackAsync(int effectId, boolean always) {
-        performHapticFeedback(effectId, always);
+    public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) {
+        performHapticFeedback(effectId, always, fromIme);
     }
 
     @Override
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index fcc8344..68940d6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1153,6 +1153,7 @@
                     }
                     final boolean startInput;
                     synchronized (mH) {
+                        mImeDispatcher.clear();
                         if (getBindSequenceLocked() != sequence) {
                             return;
                         }
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 51890ec..94c72c6 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -46,5 +46,5 @@
     name: "bal_respect_app_switch_state_when_check_bound_by_foreground_uid"
     namespace: "responsible_apis"
     description: "Prevent BAL based on it is bound by foreground Uid but the app switch is stopped."
-    bug: "171459802"
+    bug: "283801068"
 }
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index d9ac5a9..30de546 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -61,7 +61,7 @@
     private static final int PER_CHUNK_SIZE = 1024;
     private static final String TAG = "ProtoLog";
     private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
-    static final String PROTOLOG_VERSION = "1.0.0";
+    static final String PROTOLOG_VERSION = "2.0.0";
     private static final int DEFAULT_PER_CHUNK_SIZE = 0;
 
     private final File mLogFile;
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 78bed94..8965385 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -98,7 +98,7 @@
      */
     public static synchronized IProtoLog getSingleInstance() {
         if (sServiceInstance == null) {
-            if (android.tracing.Flags.perfettoProtolog()) {
+            if (android.tracing.Flags.perfettoProtologTracing()) {
                 sServiceInstance =
                         new PerfettoProtoLogImpl(sViewerConfigPath);
             } else {
diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp
index 06d5eb3..d5f17da 100644
--- a/core/jni/LayoutlibLoader.cpp
+++ b/core/jni/LayoutlibLoader.cpp
@@ -364,7 +364,7 @@
 
 // Called right before aborting by LOG_ALWAYS_FATAL. Print the pending exception.
 void abort_handler(const char* abort_message) {
-    ALOGE("Abort to abort the process...");
+    ALOGE("About to abort the process...");
 
     JNIEnv* env = NULL;
     if (javaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto
index db99e5b..9151958 100644
--- a/core/proto/android/server/vibrator/vibratormanagerservice.proto
+++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto
@@ -79,11 +79,28 @@
     repeated int32 delays = 2;
 }
 
+// Next Tag: 5
 message VibrationAttributesProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
     optional int32 usage = 1;
     optional int32 audio_usage = 2;
     optional int32 flags = 3;
+    optional int32 category = 4;
+}
+
+// Next Tag: 4
+message VibrationParamProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+    optional VibrationScaleParamProto scale = 1;
+    optional int64 create_time = 2;
+    optional bool is_from_request = 3;
+}
+
+// Next Tag: 3
+message VibrationScaleParamProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+    optional int32 types_mask = 1;
+    optional float scale = 2;
 }
 
 // Next Tag: 9
@@ -132,16 +149,19 @@
     }
 }
 
-// Next Tag: 25
+// Next Tag: 29
 message VibratorManagerServiceDumpProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
     repeated int32 vibrator_ids = 1;
     optional VibrationProto current_vibration = 2;
     optional bool is_vibrating = 3;
+    optional int32 is_vibrator_controller_registered = 27;
     optional VibrationProto current_external_vibration = 4;
     optional bool vibrator_under_external_control = 5;
     optional bool low_power_mode = 6;
     optional bool vibrate_on = 24;
+    optional bool keyboard_vibration_on = 25;
+    optional int32 default_vibration_amplitude = 26;
     optional int32 alarm_intensity = 18;
     optional int32 alarm_default_intensity = 19;
     optional int32 haptic_feedback_intensity = 7;
@@ -158,5 +178,6 @@
     repeated VibrationProto previous_notification_vibrations = 14;
     repeated VibrationProto previous_alarm_vibrations = 15;
     repeated VibrationProto previous_vibrations = 16;
-    repeated VibrationProto previous_external_vibrations = 17;
+    repeated VibrationParamProto previous_vibration_params = 28;
+    reserved 17; // prev previous_external_vibrations
 }
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6134e78..967edde 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4101,6 +4101,13 @@
     <!-- How close vibration request should be when they're aggregated for dumpsys, in ms. -->
     <integer name="config_previousVibrationsDumpAggregationTimeMillisLimit">1000</integer>
 
+    <!-- How long history of vibration control service should be kept for the dumpsys. -->
+    <integer name="config_vibratorControlServiceDumpSizeLimit">50</integer>
+
+    <!-- How close requests to vibration control service should be when they're aggregated for
+         dumpsys, in ms. -->
+    <integer name="config_vibratorControlServiceDumpAggregationTimeMillisLimit">60000</integer>
+
     <!-- The default vibration strength, must be between 1 and 255 inclusive. -->
     <integer name="config_defaultVibrationAmplitude">255</integer>
 
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index c87b7cd..5e3e1b0 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -84,7 +84,7 @@
          CarrierConfigManager#KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_STRING_ARRAY.
          If 0, the device always switch to the higher score SIM.
          If < 0, the network type and signal strength based auto switch is disabled. -->
-    <integer name="auto_data_switch_score_tolerance">4000</integer>
+    <integer name="auto_data_switch_score_tolerance">-1</integer>
     <java-symbol type="integer" name="auto_data_switch_score_tolerance" />
 
     <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2f5183f..ee51ed0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2083,6 +2083,8 @@
   <java-symbol type="integer" name="config_recentVibrationsDumpSizeLimit" />
   <java-symbol type="integer" name="config_previousVibrationsDumpSizeLimit" />
   <java-symbol type="integer" name="config_previousVibrationsDumpAggregationTimeMillisLimit" />
+  <java-symbol type="integer" name="config_vibratorControlServiceDumpSizeLimit" />
+  <java-symbol type="integer" name="config_vibratorControlServiceDumpAggregationTimeMillisLimit" />
   <java-symbol type="integer" name="config_defaultVibrationAmplitude" />
   <java-symbol type="dimen" name="config_hapticChannelMaxVibrationAmplitude" />
   <java-symbol type="dimen" name="config_keyboardHapticFeedbackFixedAmplitude" />
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
index fbb446b..36a6430 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
@@ -22,8 +22,8 @@
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
 import android.hardware.radio.UniqueProgramIdentifier;
-import android.test.suitebuilder.annotation.MediumTest;
 
+import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
diff --git a/core/tests/ConnectivityManagerTest/Android.bp b/core/tests/ConnectivityManagerTest/Android.bp
index beaf176..f17a28d 100644
--- a/core/tests/ConnectivityManagerTest/Android.bp
+++ b/core/tests/ConnectivityManagerTest/Android.bp
@@ -27,7 +27,10 @@
         "android.test.runner",
         "android.test.base",
     ],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+    ],
     // Include all test java files.
     srcs: ["src/**/*.java"],
     platform_apis: true,
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 2d291ff..32da1d8 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -22,7 +22,8 @@
 import android.net.wifi.WifiManager;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index 23135dd..9443766 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -22,9 +22,9 @@
 import android.net.wifi.WifiConfiguration.PairwiseCipher;
 import android.net.wifi.WifiConfiguration.Protocol;
 import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.WifiAssociationTestRunner;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index b37daa3..9c61647 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -18,7 +18,8 @@
 
 import android.net.wifi.WifiConfiguration;
 import android.os.SystemClock;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.WifiConfigurationHelper;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 4b82c3d..993b9ef 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -29,9 +29,10 @@
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
 import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
 import com.android.connectivitymanagertest.WifiConfigurationHelper;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
index 5c2f388..9dc3fce 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
@@ -17,19 +17,19 @@
 package com.android.connectivitymanagertest.unit;
 
 import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.Context;
 import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
+import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.Status;
-import android.net.wifi.SupplicantState;
-
-import android.test.suitebuilder.annotation.LargeTest;
+import android.net.wifi.WifiManager;
 import android.test.AndroidTestCase;
 
+import androidx.test.filters.LargeTest;
+
 import java.util.List;
 
 /**
diff --git a/core/tests/bandwidthtests/Android.bp b/core/tests/bandwidthtests/Android.bp
index d0b42f7..8645b39 100644
--- a/core/tests/bandwidthtests/Android.bp
+++ b/core/tests/bandwidthtests/Android.bp
@@ -31,6 +31,9 @@
         "org.apache.http.legacy",
         "android.test.base",
     ],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+    ],
     platform_apis: true,
 }
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 4b42f4ae..b2c85a2 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -30,9 +30,10 @@
 import android.os.SystemClock;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.bandwidthtest.util.BandwidthTestUtil;
 import com.android.bandwidthtest.util.ConnectionUtil;
 
diff --git a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
index aaa199d..e8b295b 100644
--- a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.hardware.usb.UsbDevice;
 import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -58,6 +59,7 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
+    private AccessibilityService mAccessibilityService;
     private BrailleDisplayController mBrailleDisplayController;
 
     @Mock
@@ -76,12 +78,13 @@
     @Before
     public void test() {
         MockitoAnnotations.initMocks(this);
-        AccessibilityService accessibilityService = spy(new TestAccessibilityService());
-        doReturn((Executor) Runnable::run).when(accessibilityService).getMainExecutor();
-        doReturn(TEST_SERVICE_CONNECTION_ID).when(accessibilityService).getConnectionId();
+        mAccessibilityService = spy(new TestAccessibilityService());
+        doReturn((Executor) Runnable::run).when(mAccessibilityService).getMainExecutor();
+        doReturn(TEST_SERVICE_CONNECTION_ID).when(mAccessibilityService).getConnectionId();
         AccessibilityInteractionClient.addConnection(TEST_SERVICE_CONNECTION_ID,
                 mAccessibilityServiceConnection, /*initializeCache=*/false);
-        mBrailleDisplayController = accessibilityService.getBrailleDisplayController();
+        mBrailleDisplayController = new BrailleDisplayControllerImpl(
+                mAccessibilityService, new Object(), /*isHidrawSupported=*/true);
     }
 
     // Automated CTS tests only use the BluetoothDevice version of BrailleDisplayController#connect
@@ -104,4 +107,17 @@
         assertThrows(IllegalStateException.class,
                 () -> mBrailleDisplayController.connect(usbDevice, mBrailleDisplayCallback));
     }
+
+    @Test
+    public void connect_HidrawNotSupported_callsOnConnectionFailed() {
+        BrailleDisplayController controller = new BrailleDisplayControllerImpl(
+                mAccessibilityService, new Object(), /*isHidrawSupported=*/false);
+        UsbDevice usbDevice = Mockito.mock(UsbDevice.class);
+
+        controller.connect(usbDevice, mBrailleDisplayCallback);
+
+        verify(mBrailleDisplayCallback).onConnectionFailed(
+                BrailleDisplayController.BrailleDisplayCallback.FLAG_ERROR_CANNOT_ACCESS);
+        verifyZeroInteractions(mAccessibilityServiceConnection);
+    }
 }
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 64c17bd..d115bf3 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -247,7 +247,7 @@
             newConfig.smallestScreenWidthDp++;
             transaction = newTransaction(activityThread);
             transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain(
-                    activity.getActivityToken(), newConfig));
+                    activity.getActivityToken(), newConfig, new ActivityWindowInfo()));
             appThread.scheduleTransaction(transaction);
             InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
@@ -455,11 +455,11 @@
 
         transaction = newTransaction(activityThread);
         transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain(
-                activity.getActivityToken(), activityConfigLandscape));
+                activity.getActivityToken(), activityConfigLandscape, new ActivityWindowInfo()));
         transaction.addTransactionItem(ConfigurationChangeItem.obtain(
                 processConfigPortrait, DEVICE_ID_INVALID));
         transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain(
-                activity.getActivityToken(), activityConfigPortrait));
+                activity.getActivityToken(), activityConfigPortrait, new ActivityWindowInfo()));
         appThread.scheduleTransaction(transaction);
 
         activity.mTestLatch.await(TIMEOUT_SEC, TimeUnit.SECONDS);
@@ -883,7 +883,7 @@
     private static ClientTransaction newActivityConfigTransaction(@NonNull Activity activity,
             @NonNull Configuration config) {
         final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain(
-                activity.getActivityToken(), config);
+                activity.getActivityToken(), config, new ActivityWindowInfo());
 
         final ClientTransaction transaction = newTransaction(activity);
         transaction.addTransactionItem(item);
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
index 85a1b4e..4db5d1b 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java
@@ -107,7 +107,7 @@
     @Test
     public void testActivityConfigurationChangeItem_getContextToUpdate() {
         final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem
-                .obtain(mActivityToken, mConfiguration);
+                .obtain(mActivityToken, mConfiguration, new ActivityWindowInfo());
         final Context context = item.getContextToUpdate(mHandler);
 
         assertEquals(mActivity, context);
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 906558f..31ea675 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -82,7 +82,8 @@
 
     @Test
     public void testRecycleActivityConfigurationChangeItem() {
-        testRecycle(() -> ActivityConfigurationChangeItem.obtain(mActivityToken, config()));
+        testRecycle(() -> ActivityConfigurationChangeItem.obtain(mActivityToken, config(),
+                new ActivityWindowInfo()));
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index dbb090f..75347bf 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -95,8 +95,11 @@
     @Test
     public void testActivityConfigChange() {
         // Write to parcel
+        final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo();
+        activityWindowInfo.set(true /* isEmbedded */, new Rect(0, 0, 500, 1000),
+                new Rect(0, 0, 500, 500));
         ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain(
-                mActivityToken, config());
+                mActivityToken, config(), activityWindowInfo);
         writeAndPrepareForReading(item);
 
         // Read from parcel and assert
@@ -300,7 +303,7 @@
         // Write to parcel
         NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true);
         ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
-                mActivityToken, config());
+                mActivityToken, config(), new ActivityWindowInfo());
 
         StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken,
                 78 /* configChanges */);
@@ -327,7 +330,7 @@
         // Write to parcel
         NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true);
         ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
-                mActivityToken, config());
+                mActivityToken, config(), new ActivityWindowInfo());
 
         ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         transaction.addTransactionItem(callback1);
diff --git a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
index 9dce899..da40f2a 100644
--- a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
+++ b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java
@@ -29,8 +29,8 @@
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.PersistableBundle;
-import android.test.suitebuilder.annotation.LargeTest;
 
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
index fae7148..3618543 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
@@ -18,8 +18,7 @@
 
 import static junit.framework.Assert.fail;
 
-import android.test.suitebuilder.annotation.SmallTest;
-
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.ArrayUtils;
diff --git a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
index da3a465..b61104d 100644
--- a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
+++ b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
@@ -27,7 +27,8 @@
 import android.hardware.biometrics.face.SensorProps;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
index 613089c..f058c16 100644
--- a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
+++ b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
@@ -27,7 +27,8 @@
 import android.hardware.biometrics.fingerprint.SensorProps;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -38,7 +39,6 @@
 
 import java.util.function.Function;
 
-
 @Presubmit
 @SmallTest
 public class FingerprintSensorConfigurationsTest {
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 7c58de6..1a242ef 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -451,7 +451,7 @@
         ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, display);
 
         boolean result = viewRootImpl.performHapticFeedback(
-                HapticFeedbackConstants.CONTEXT_CLICK, true);
+                HapticFeedbackConstants.CONTEXT_CLICK, true, false /* fromIme */);
 
         assertThat(result).isFalse();
     }
diff --git a/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java b/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java
index 3160428..cb8b0db 100644
--- a/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java
+++ b/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java
@@ -24,9 +24,9 @@
 import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.Settings;
-import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 4edfb09..051e73f 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -584,6 +584,8 @@
         <permission name="android.permission.DOMAIN_VERIFICATION_AGENT"/>
         <!-- Permission required for CTS test CtsInputTestCases -->
         <permission name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" />
+        <!-- Permission required for CTS test - PackageManagerShellCommandInstallTest -->
+        <permission name="android.permission.EMERGENCY_INSTALL_PACKAGES" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index e8c7a53..0231d3a 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1,5 +1,5 @@
 {
-  "version": "1.0.0",
+  "version": "2.0.0",
   "messages": {
     "7286191062634870297": {
       "message": "Binding proc %s with config %s",
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
index 08b7bb8..39cface 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
@@ -201,7 +201,7 @@
             return null;
         }
         return new SplitInfo(primaryActivityStack, secondaryActivityStack,
-                mCurrentSplitAttributes, mToken);
+                mCurrentSplitAttributes, SplitInfo.Token.createFromBinder(mToken));
     }
 
     static boolean shouldFinishPrimaryWithSecondary(@NonNull SplitRule splitRule) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index ae3a854..038d008 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -35,6 +35,7 @@
 import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED;
 import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED;
 
+import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_ACTIVITY_STACK_TOKEN;
 import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG;
 import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
 import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
@@ -112,10 +113,6 @@
     static final boolean ENABLE_SHELL_TRANSITIONS =
             SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
 
-    // TODO(b/295993745): remove after prebuilt library is updated.
-    private static final String KEY_ACTIVITY_STACK_TOKEN =
-            "androidx.window.extensions.embedding.ActivityStackToken";
-
     @VisibleForTesting
     @GuardedBy("mLock")
     final SplitPresenter mPresenter;
@@ -554,7 +551,7 @@
     }
 
     @Override
-    public void updateActivityStackAttributes(@NonNull IBinder activityStackToken,
+    public void updateActivityStackAttributes(@NonNull ActivityStack.Token activityStackToken,
                                               @NonNull ActivityStackAttributes attributes) {
         if (!Flags.activityEmbeddingOverlayPresentationFlag()) {
             return;
@@ -563,7 +560,7 @@
         Objects.requireNonNull(attributes);
 
         synchronized (mLock) {
-            final TaskFragmentContainer container = getContainer(activityStackToken);
+            final TaskFragmentContainer container = getContainer(activityStackToken.getRawToken());
             if (container == null) {
                 Log.w(TAG, "Cannot find TaskFragmentContainer for token:" + activityStackToken);
                 return;
@@ -583,13 +580,14 @@
 
     @Override
     @Nullable
-    public ParentContainerInfo getParentContainerInfo(@NonNull IBinder activityStackToken) {
+    public ParentContainerInfo getParentContainerInfo(
+            @NonNull ActivityStack.Token activityStackToken) {
         if (!Flags.activityEmbeddingOverlayPresentationFlag()) {
             return null;
         }
         Objects.requireNonNull(activityStackToken);
         synchronized (mLock) {
-            final TaskFragmentContainer container = getContainer(activityStackToken);
+            final TaskFragmentContainer container = getContainer(activityStackToken.getRawToken());
             if (container == null) {
                 return null;
             }
@@ -601,7 +599,7 @@
 
     @Override
     @Nullable
-    public IBinder getActivityStackToken(@NonNull String tag) {
+    public ActivityStack.Token getActivityStackToken(@NonNull String tag) {
         if (!Flags.activityEmbeddingOverlayPresentationFlag()) {
             return null;
         }
@@ -612,7 +610,8 @@
             if (taskFragmentContainer == null) {
                 return null;
             }
-            return taskFragmentContainer.getTaskFragmentToken();
+            return ActivityStack.Token.createFromBinder(taskFragmentContainer
+                    .getTaskFragmentToken());
         }
     }
 
@@ -2761,8 +2760,10 @@
             // TODO(b/232042367): Consolidate the activity create handling so that we can handle
             // cross-process the same as normal.
 
-            IBinder activityStackToken = options.getBinder(KEY_ACTIVITY_STACK_TOKEN);
-            if (activityStackToken != null) {
+            final Bundle bundle = options.getBundle(KEY_ACTIVITY_STACK_TOKEN);
+            if (bundle != null) {
+                final IBinder activityStackToken = ActivityStack.Token.readFromBundle(bundle)
+                        .getRawToken();
                 // Put activityStack token to #KEY_LAUNCH_TASK_FRAGMENT_TOKEN to launch the activity
                 // into the taskFragment associated with the token.
                 options.putBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN, activityStackToken);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 6fe8e50..a6bf99d 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -367,7 +367,8 @@
         if (activities == null) {
             return null;
         }
-        return new ActivityStack(activities, isEmpty(), mToken, mOverlayTag);
+        return new ActivityStack(activities, isEmpty(),
+                ActivityStack.Token.createFromBinder(mToken), mOverlayTag);
     }
 
     /** Adds the activity that will be reparented to this container. */
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 34d43ad..28fbadb 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -399,7 +399,8 @@
                         new ActivityStackAttributes.Builder().build()));
 
         assertThrows(NullPointerException.class, () ->
-                mSplitController.updateActivityStackAttributes(new Binder(), null));
+                mSplitController.updateActivityStackAttributes(
+                        ActivityStack.Token.createFromBinder(new Binder()), null));
 
         verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any());
     }
@@ -408,7 +409,8 @@
     public void testUpdateActivityStackAttributes_nullContainer_earlyReturn() {
         final TaskFragmentContainer container = mSplitController.newContainer(mActivity,
                 mActivity.getTaskId());
-        mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(),
+        mSplitController.updateActivityStackAttributes(
+                ActivityStack.Token.createFromBinder(container.getTaskFragmentToken()),
                 new ActivityStackAttributes.Builder().build());
 
         verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any());
@@ -418,7 +420,8 @@
     public void testUpdateActivityStackAttributes_notOverlay_earlyReturn() {
         final TaskFragmentContainer container = createMockTaskFragmentContainer(mActivity);
 
-        mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(),
+        mSplitController.updateActivityStackAttributes(
+                ActivityStack.Token.createFromBinder(container.getTaskFragmentToken()),
                 new ActivityStackAttributes.Builder().build());
 
         verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any());
@@ -431,7 +434,8 @@
         final ActivityStackAttributes attrs = new ActivityStackAttributes.Builder().build();
         final IBinder token = container.getTaskFragmentToken();
 
-        mSplitController.updateActivityStackAttributes(token, attrs);
+        mSplitController.updateActivityStackAttributes(ActivityStack.Token.createFromBinder(token),
+                attrs);
 
         verify(mSplitPresenter).applyActivityStackAttributes(any(), eq(container), eq(attrs),
                 any());
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index b60943a..00f8b59 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -1437,7 +1437,7 @@
     @Test
     public void testUpdateSplitAttributes_nullParams_throwException() {
         assertThrows(NullPointerException.class,
-                () -> mSplitController.updateSplitAttributes(null, SPLIT_ATTRIBUTES));
+                () -> mSplitController.updateSplitAttributes((IBinder) null, SPLIT_ATTRIBUTES));
 
         final SplitContainer splitContainer = mock(SplitContainer.class);
         final IBinder token = new Binder();
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 0ecf1f8..8829d1b 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -212,76 +212,3 @@
     plugins: ["dagger2-compiler"],
     use_resource_processor: true,
 }
-
-android_app {
-    name: "WindowManagerShellRobolectric",
-    platform_apis: true,
-    static_libs: [
-        "WindowManager-Shell",
-    ],
-    manifest: "multivalentTests/AndroidManifestRobolectric.xml",
-    use_resource_processor: true,
-}
-
-android_robolectric_test {
-    name: "WMShellRobolectricTests",
-    instrumentation_for: "WindowManagerShellRobolectric",
-    upstream: true,
-    java_resource_dirs: [
-        "multivalentTests/robolectric/config",
-    ],
-    srcs: [
-        "multivalentTests/src/**/*.kt",
-    ],
-    // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed.
-    exclude_srcs: ["multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"],
-    static_libs: [
-        "junit",
-        "androidx.test.runner",
-        "androidx.test.rules",
-        "androidx.test.ext.junit",
-        "mockito-robolectric-prebuilt",
-        "mockito-kotlin2",
-        "truth",
-    ],
-}
-
-android_test {
-    name: "WMShellMultivalentTestsOnDevice",
-    srcs: [
-        "multivalentTests/src/**/*.kt",
-    ],
-    static_libs: [
-        "WindowManager-Shell",
-        "junit",
-        "androidx.test.runner",
-        "androidx.test.rules",
-        "androidx.test.ext.junit",
-        "frameworks-base-testutils",
-        "mockito-kotlin2",
-        "mockito-target-extended-minus-junit4",
-        "truth",
-        "platform-test-annotations",
-        "platform-test-rules",
-    ],
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    jni_libs: [
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-    kotlincflags: ["-Xjvm-default=all"],
-    optimize: {
-        enabled: false,
-    },
-    test_suites: ["device-tests"],
-    platform_apis: true,
-    certificate: "platform",
-    aaptflags: [
-        "--extra-packages",
-        "com.android.wm.shell",
-    ],
-    manifest: "multivalentTests/AndroidManifest.xml",
-}
diff --git a/libs/WindowManager/Shell/multivalentTests/Android.bp b/libs/WindowManager/Shell/multivalentTests/Android.bp
new file mode 100644
index 0000000..1686d0d
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/Android.bp
@@ -0,0 +1,97 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+    default_team: "trendy_team_multitasking_windowing",
+}
+
+android_app {
+    name: "WindowManagerShellRobolectric",
+    platform_apis: true,
+    static_libs: [
+        "WindowManager-Shell",
+    ],
+    manifest: "AndroidManifestRobolectric.xml",
+    use_resource_processor: true,
+}
+
+android_robolectric_test {
+    name: "WMShellRobolectricTests",
+    instrumentation_for: "WindowManagerShellRobolectric",
+    upstream: true,
+    java_resource_dirs: [
+        "robolectric/config",
+    ],
+    srcs: [
+        "src/**/*.kt",
+    ],
+    // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed.
+    exclude_srcs: ["src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"],
+    static_libs: [
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "mockito-robolectric-prebuilt",
+        "mockito-kotlin2",
+        "truth",
+    ],
+    auto_gen_config: true,
+}
+
+android_test {
+    name: "WMShellMultivalentTestsOnDevice",
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "WindowManager-Shell",
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "frameworks-base-testutils",
+        "mockito-kotlin2",
+        "mockito-target-extended-minus-junit4",
+        "truth",
+        "platform-test-annotations",
+        "platform-test-rules",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    kotlincflags: ["-Xjvm-default=all"],
+    optimize: {
+        enabled: false,
+    },
+    test_suites: ["device-tests"],
+    platform_apis: true,
+    certificate: "platform",
+    aaptflags: [
+        "--extra-packages",
+        "com.android.wm.shell",
+    ],
+    manifest: "AndroidManifest.xml",
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
index 93893e3..ef9bf00 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
@@ -51,7 +51,7 @@
         final ILogger logger = pw::println;
         switch (args[0]) {
             case "status": {
-                if (android.tracing.Flags.perfettoProtolog()) {
+                if (android.tracing.Flags.perfettoProtologTracing()) {
                     pw.println("(Deprecated) legacy command. Use Perfetto commands instead.");
                     return false;
                 }
@@ -59,7 +59,7 @@
                 return true;
             }
             case "start": {
-                if (android.tracing.Flags.perfettoProtolog()) {
+                if (android.tracing.Flags.perfettoProtologTracing()) {
                     pw.println("(Deprecated) legacy command. Use Perfetto commands instead.");
                     return false;
                 }
@@ -67,7 +67,7 @@
                 return true;
             }
             case "stop": {
-                if (android.tracing.Flags.perfettoProtolog()) {
+                if (android.tracing.Flags.perfettoProtologTracing()) {
                     pw.println("(Deprecated) legacy command. Use Perfetto commands instead.");
                     return false;
                 }
@@ -101,7 +101,7 @@
                 return mShellProtoLog.stopLoggingToLogcat(groups, logger) == 0;
             }
             case "save-for-bugreport": {
-                if (android.tracing.Flags.perfettoProtolog()) {
+                if (android.tracing.Flags.perfettoProtologTracing()) {
                     pw.println("(Deprecated) legacy command");
                     return false;
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index f757e1c..fb3c35b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -201,9 +201,11 @@
     @Provides
     static WindowDecorViewModel provideWindowDecorViewModel(
             Context context,
+            @ShellMainThread ShellExecutor mainExecutor,
             @ShellMainThread Handler mainHandler,
             @ShellMainThread Choreographer mainChoreographer,
             ShellInit shellInit,
+            IWindowManager windowManager,
             ShellCommandHandler shellCommandHandler,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
@@ -216,10 +218,12 @@
         if (DesktopModeStatus.isEnabled()) {
             return new DesktopModeWindowDecorViewModel(
                     context,
+                    mainExecutor,
                     mainHandler,
                     mainChoreographer,
                     shellInit,
                     shellCommandHandler,
+                    windowManager,
                     taskOrganizer,
                     displayController,
                     shellController,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 96eaa1e..91e9601 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -190,6 +190,7 @@
         mRelayoutParams.mShadowRadiusId = shadowRadiusID;
         mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
         mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
+        mRelayoutParams.mAllowCaptionInputFallthrough = false;
 
         relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
         // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index caa894f..8d798a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -48,9 +48,13 @@
 import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.Choreographer;
 import android.view.GestureDetector;
+import android.view.ISystemGestureExclusionListener;
+import android.view.IWindowManager;
 import android.view.InputChannel;
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
@@ -73,6 +77,7 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
@@ -88,6 +93,7 @@
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
+import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 
 import java.io.PrintWriter;
 import java.util.Optional;
@@ -102,6 +108,8 @@
     private static final String TAG = "DesktopModeWindowDecorViewModel";
 
     private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory;
+    private final IWindowManager mWindowManager;
+    private final ShellExecutor mMainExecutor;
     private final ActivityTaskManager mActivityTaskManager;
     private final ShellCommandHandler mShellCommandHandler;
     private final ShellTaskOrganizer mTaskOrganizer;
@@ -112,6 +120,8 @@
     private final DisplayController mDisplayController;
     private final SyncTransactionQueue mSyncQueue;
     private final Optional<DesktopTasksController> mDesktopTasksController;
+    private final InputManager mInputManager;
+
     private boolean mTransitionDragActive;
 
     private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -135,14 +145,31 @@
             new DesktopModeKeyguardChangeListener();
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final DisplayInsetsController mDisplayInsetsController;
+    private final Region mExclusionRegion = Region.obtain();
     private boolean mInImmersiveMode;
 
+    private final ISystemGestureExclusionListener mGestureExclusionListener =
+            new ISystemGestureExclusionListener.Stub() {
+                @Override
+                public void onSystemGestureExclusionChanged(int displayId,
+                        Region systemGestureExclusion, Region systemGestureExclusionUnrestricted) {
+                    if (mContext.getDisplayId() != displayId) {
+                        return;
+                    }
+                    mMainExecutor.execute(() -> {
+                        mExclusionRegion.set(systemGestureExclusion);
+                    });
+                }
+            };
+
     public DesktopModeWindowDecorViewModel(
             Context context,
+            ShellExecutor shellExecutor,
             Handler mainHandler,
             Choreographer mainChoreographer,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
+            IWindowManager windowManager,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             ShellController shellController,
@@ -154,10 +181,12 @@
     ) {
         this(
                 context,
+                shellExecutor,
                 mainHandler,
                 mainChoreographer,
                 shellInit,
                 shellCommandHandler,
+                windowManager,
                 taskOrganizer,
                 displayController,
                 shellController,
@@ -174,10 +203,12 @@
     @VisibleForTesting
     DesktopModeWindowDecorViewModel(
             Context context,
+            ShellExecutor shellExecutor,
             Handler mainHandler,
             Choreographer mainChoreographer,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
+            IWindowManager windowManager,
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             ShellController shellController,
@@ -190,6 +221,7 @@
             Supplier<SurfaceControl.Transaction> transactionFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
         mContext = context;
+        mMainExecutor = shellExecutor;
         mMainHandler = mainHandler;
         mMainChoreographer = mainChoreographer;
         mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
@@ -201,10 +233,12 @@
         mTransitions = transitions;
         mDesktopTasksController = desktopTasksController;
         mShellCommandHandler = shellCommandHandler;
+        mWindowManager = windowManager;
         mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory;
         mInputMonitorFactory = inputMonitorFactory;
         mTransactionFactory = transactionFactory;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+        mInputManager = mContext.getSystemService(InputManager.class);
 
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -216,6 +250,12 @@
                 new DesktopModeOnInsetsChangedListener());
         mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener(
                 new DeskopModeOnTaskResizeAnimationListener()));
+        try {
+            mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener,
+                    mContext.getDisplayId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register window manager callbacks", e);
+        }
     }
 
     @Override
@@ -315,12 +355,19 @@
             implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
             View.OnGenericMotionListener , DragDetector.MotionEventHandler {
         private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150;
+
         private final int mTaskId;
         private final WindowContainerToken mTaskToken;
         private final DragPositioningCallback mDragPositioningCallback;
         private final DragDetector mDragDetector;
         private final GestureDetector mGestureDetector;
 
+        /**
+         * Whether to pilfer the next motion event to send cancellations to the windows below.
+         * Useful when the caption window is spy and the gesture should be handle by the system
+         * instead of by the app for their custom header content.
+         */
+        private boolean mShouldPilferCaptionEvents;
         private boolean mIsDragging;
         private boolean mTouchscreenInUse;
         private boolean mHasLongClicked;
@@ -438,6 +485,40 @@
             final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
             moveTaskToFront(decoration.mTaskInfo);
 
+            final int actionMasked = e.getActionMasked();
+            final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN;
+            final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL
+                    || actionMasked == MotionEvent.ACTION_UP;
+            if (isDown) {
+                final boolean downInCustomizableCaptionRegion =
+                        decoration.checkTouchEventInCustomizableRegion(e);
+                final boolean downInExclusionRegion = mExclusionRegion.contains(
+                        (int) e.getRawX(), (int) e.getRawY());
+                final boolean isTransparentCaption =
+                        TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo);
+                // The caption window may be a spy window when the caption background is
+                // transparent, which means events will fall through to the app window. Make
+                // sure to cancel these events if they do not happen in the intersection of the
+                // customizable region and what the app reported as exclusion areas, because
+                // the drag-move or other caption gestures should take priority outside those
+                // regions.
+                mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion
+                        && downInExclusionRegion && isTransparentCaption);
+            }
+
+            if (!mShouldPilferCaptionEvents) {
+                // The event will be handled by a window below.
+                return false;
+            }
+            // Otherwise pilfer so that windows below receive cancellations for this gesture, and
+            // continue normal handling as a caption gesture.
+            if (mInputManager != null) {
+                mInputManager.pilferPointers(v.getViewRootImpl().getInputToken());
+            }
+            if (isUpOrCancel) {
+                // Gesture is finished, reset state.
+                mShouldPilferCaptionEvents = false;
+            }
             if (!mHasLongClicked && id != R.id.maximize_window) {
                 decoration.closeMaximizeMenuIfNeeded(e);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 74f460b..9e999ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -56,6 +56,7 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
+import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
@@ -337,6 +338,8 @@
             controlsElement.mWidthResId = R.dimen.desktop_mode_right_edge_buttons_width;
             controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
             relayoutParams.mOccludingCaptionElements.add(controlsElement);
+            relayoutParams.mAllowCaptionInputFallthrough =
+                    TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo);
         }
         if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) {
             relayoutParams.mShadowRadiusId = taskInfo.isFocused
@@ -699,6 +702,13 @@
     }
 
     /**
+     * Checks whether the touch event falls inside the customizable caption region.
+     */
+    boolean checkTouchEventInCustomizableRegion(MotionEvent ev) {
+        return mResult.mCustomizableCaptionRegion.contains((int) ev.getRawX(), (int) ev.getRawY());
+    }
+
+    /**
      * Check a passed MotionEvent if a click has occurred on any button on this caption
      * Note this should only be called when a regular onClick is not possible
      * (i.e. the button was clicked through status bar layer)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index dc65855..32c2d1e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -31,6 +31,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Binder;
 import android.view.Display;
 import android.view.InsetsSource;
@@ -311,6 +312,10 @@
                 if (numOfElements == 0) {
                     boundingRects = null;
                 } else {
+                    // The customizable region can at most be equal to the caption bar.
+                    if (params.mAllowCaptionInputFallthrough) {
+                        outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect);
+                    }
                     boundingRects = new Rect[numOfElements];
                     for (int i = 0; i < numOfElements; i++) {
                         final OccludingCaptionElement element =
@@ -319,9 +324,14 @@
                                 resources.getDimensionPixelSize(element.mWidthResId);
                         boundingRects[i] =
                                 calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect);
+                        // Subtract the regions used by the caption elements, the rest is
+                        // customizable.
+                        if (params.mAllowCaptionInputFallthrough) {
+                            outResult.mCustomizableCaptionRegion.op(boundingRects[i],
+                                    Region.Op.DIFFERENCE);
+                        }
                     }
                 }
-
                 // Add this caption as an inset source.
                 wct.addInsetsSource(mTaskInfo.token,
                         mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect,
@@ -389,6 +399,11 @@
                         WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
         lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
         lp.setTrustedOverlay();
+        if (params.mAllowCaptionInputFallthrough) {
+            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+        } else {
+            lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+        }
         if (mViewHost == null) {
             mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay,
                     mCaptionWindowManager);
@@ -596,6 +611,7 @@
         int mCaptionHeightId;
         int mCaptionWidthId;
         final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>();
+        boolean mAllowCaptionInputFallthrough;
 
         int mShadowRadiusId;
         int mCornerRadius;
@@ -610,6 +626,7 @@
             mCaptionHeightId = Resources.ID_NULL;
             mCaptionWidthId = Resources.ID_NULL;
             mOccludingCaptionElements.clear();
+            mAllowCaptionInputFallthrough = false;
 
             mShadowRadiusId = Resources.ID_NULL;
             mCornerRadius = 0;
@@ -637,6 +654,7 @@
         int mCaptionHeight;
         int mCaptionWidth;
         int mCaptionX;
+        final Region mCustomizableCaptionRegion = Region.obtain();
         int mWidth;
         int mHeight;
         T mRootView;
@@ -647,6 +665,7 @@
             mCaptionHeight = 0;
             mCaptionWidth = 0;
             mCaptionX = 0;
+            mCustomizableCaptionRegion.setEmpty();
             mRootView = null;
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt
new file mode 100644
index 0000000..5dd96ac
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wm.shell.windowdecor.extension
+
+import android.app.TaskInfo
+import android.view.WindowInsetsController.APPEARANCE_LIGHT_CAPTION_BARS
+import android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND
+
+val TaskInfo.isTransparentCaptionBarAppearance: Boolean
+    get() {
+        val appearance = taskDescription?.statusBarAppearance ?: 0
+        return (appearance and APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND) != 0
+    }
+
+val TaskInfo.isLightCaptionBarAppearance: Boolean
+    get() {
+        val appearance = taskDescription?.statusBarAppearance ?: 0
+        return (appearance and APPEARANCE_LIGHT_CAPTION_BARS) != 0
+    }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
index 7e5b9bd..b7dd01f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -8,8 +8,6 @@
 import android.graphics.Color
 import android.view.View
 import android.view.View.OnLongClickListener
-import android.view.WindowInsetsController.APPEARANCE_LIGHT_CAPTION_BARS
-import android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND
 import android.widget.ImageButton
 import android.widget.ImageView
 import android.widget.TextView
@@ -22,6 +20,8 @@
 import com.android.internal.R.attr.materialColorSurfaceDim
 import com.android.wm.shell.R
 import com.android.wm.shell.windowdecor.MaximizeButtonView
+import com.android.wm.shell.windowdecor.extension.isLightCaptionBarAppearance
+import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppearance
 
 /**
  * A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
@@ -107,7 +107,7 @@
 
     @ColorInt
     private fun getCaptionBackgroundColor(taskInfo: RunningTaskInfo): Int {
-        if (isTransparentBackgroundRequested(taskInfo)) {
+        if (taskInfo.isTransparentCaptionBarAppearance) {
             return Color.TRANSPARENT
         }
         val materialColorAttr: Int =
@@ -133,10 +133,10 @@
     @ColorInt
     private fun getAppNameAndButtonColor(taskInfo: RunningTaskInfo): Int {
         val materialColorAttr = when {
-            isTransparentBackgroundRequested(taskInfo) &&
-                    isLightCaptionBar(taskInfo) -> materialColorOnSecondaryContainer
-            isTransparentBackgroundRequested(taskInfo) &&
-                    !isLightCaptionBar(taskInfo) -> materialColorOnSurface
+            taskInfo.isTransparentCaptionBarAppearance &&
+                    taskInfo.isLightCaptionBarAppearance -> materialColorOnSecondaryContainer
+            taskInfo.isTransparentCaptionBarAppearance &&
+                    !taskInfo.isLightCaptionBarAppearance -> materialColorOnSurface
             isDarkMode() -> materialColorOnSurface
             else -> materialColorOnSecondaryContainer
         }
@@ -167,16 +167,6 @@
                 Configuration.UI_MODE_NIGHT_YES
     }
 
-    private fun isTransparentBackgroundRequested(taskInfo: RunningTaskInfo): Boolean {
-        val appearance = taskInfo.taskDescription?.statusBarAppearance ?: 0
-        return (appearance and APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND) != 0
-    }
-
-    private fun isLightCaptionBar(taskInfo: RunningTaskInfo): Boolean {
-        val appearance = taskInfo.taskDescription?.statusBarAppearance ?: 0
-        return (appearance and APPEARANCE_LIGHT_CAPTION_BARS) != 0
-    }
-
     companion object {
         private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder"
         private const val DARK_THEME_UNFOCUSED_OPACITY = 140 // 55%
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index d4e9ac9..e74c804 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -36,7 +36,6 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 import android.os.RemoteException;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.Rational;
@@ -45,6 +44,8 @@
 import android.view.SurfaceControl;
 import android.window.WindowContainerToken;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.wm.shell.MockSurfaceControlHelper;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 5d968d3..3384509 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -42,10 +42,11 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayController;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
index 45f6c8c..72db6e0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java
@@ -23,20 +23,21 @@
 import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_FULLSCREEN;
 import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE;
 
-import static java.util.Collections.EMPTY_LIST;
-
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import static java.util.Collections.EMPTY_LIST;
+
 import android.app.PendingIntent;
 import android.app.RemoteAction;
 import android.graphics.drawable.Icon;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.pip.PipMediaController;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
index 0504439..fbc0db9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
@@ -32,7 +32,6 @@
 import android.app.ActivityManager;
 import android.graphics.Rect;
 import android.os.IBinder;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.SurfaceControl;
@@ -40,6 +39,8 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.transition.Transitions;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index f84685a..917fd71 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -31,6 +31,7 @@
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Choreographer
 import android.view.Display.DEFAULT_DISPLAY
+import android.view.IWindowManager
 import android.view.InputChannel
 import android.view.InputMonitor
 import android.view.InsetsSource
@@ -96,6 +97,7 @@
     @Mock private lateinit var mockShellExecutor: ShellExecutor
     @Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
     @Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
+    @Mock private lateinit var mockWindowManager: IWindowManager
 
     private val transactionFactory = Supplier<SurfaceControl.Transaction> {
         SurfaceControl.Transaction()
@@ -110,10 +112,12 @@
         shellInit = ShellInit(mockShellExecutor)
         desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
                 mContext,
+                mockShellExecutor,
                 mockMainHandler,
                 mockMainChoreographer,
                 shellInit,
                 mockShellCommandHandler,
+                mockWindowManager,
                 mockTaskOrganizer,
                 mockDisplayController,
                 mockShellController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 40e61dd..9e62bd2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -16,6 +16,10 @@
 
 package com.android.wm.shell.windowdecor;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.any;
@@ -168,6 +172,57 @@
         assertThat(relayoutParams.mCornerRadius).isGreaterThan(0);
     }
 
+    @Test
+    public void updateRelayoutParams_freeformAndTransparent_allowsInputFallthrough() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        taskInfo.taskDescription.setStatusBarAppearance(
+                APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isTrue();
+    }
+
+    @Test
+    public void updateRelayoutParams_freeformButOpaque_disallowsInputFallthrough() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        taskInfo.taskDescription.setStatusBarAppearance(0);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+    }
+
+    @Test
+    public void updateRelayoutParams_fullscreen_disallowsInputFallthrough() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+    }
+
     private void fillRoundedCornersResources(int fillValue) {
         when(mMockRoundedCornersRadiusArray.getDimensionPixelSize(anyInt(), anyInt()))
                 .thenReturn(fillValue);
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index f0c6395..49254d1 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -81,7 +81,7 @@
   std::string overlay_path(loaded_idmap->OverlayApkPath());
   auto fd = unique_fd(base::utf8::open(overlay_path.c_str(), O_RDONLY | O_CLOEXEC));
   std::unique_ptr<AssetsProvider> overlay_assets;
-  if (IsFabricatedOverlay(fd)) {
+  if (IsFabricatedOverlayName(overlay_path) && IsFabricatedOverlay(fd)) {
     // Fabricated overlays do not contain resource definitions. All of the overlay resource values
     // are defined inline in the idmap.
     overlay_assets = EmptyAssetsProvider::Create(std::move(overlay_path));
@@ -137,8 +137,7 @@
       return {};
     }
     loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags);
-  } else if (loaded_idmap != nullptr &&
-      IsFabricatedOverlay(std::string(loaded_idmap->OverlayApkPath()))) {
+  } else if (loaded_idmap != nullptr && IsFabricatedOverlay(loaded_idmap->OverlayApkPath())) {
     loaded_arsc = LoadedArsc::Load(loaded_idmap.get());
   } else {
     loaded_arsc = LoadedArsc::CreateEmpty();
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index 5f98b8f..9824190 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -18,8 +18,10 @@
 
 #include "androidfw/Idmap.h"
 
+#include "android-base/file.h"
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "android-base/utf8.h"
 #include "androidfw/misc.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/Util.h"
@@ -250,7 +252,12 @@
 }
 } // namespace
 
-LoadedIdmap::LoadedIdmap(std::string&& idmap_path, const Idmap_header* header,
+// O_PATH is a lightweight way of creating an FD, only exists on Linux
+#ifndef O_PATH
+#define O_PATH (0)
+#endif
+
+LoadedIdmap::LoadedIdmap(const std::string& idmap_path, const Idmap_header* header,
                          const Idmap_data_header* data_header,
                          const Idmap_target_entry* target_entries,
                          const Idmap_target_entry_inline* target_inline_entries,
@@ -267,10 +274,10 @@
       configurations_(configs),
       overlay_entries_(overlay_entries),
       string_pool_(std::move(string_pool)),
-      idmap_path_(std::move(idmap_path)),
+      idmap_fd_(android::base::utf8::open(idmap_path.c_str(), O_RDONLY|O_CLOEXEC|O_BINARY|O_PATH)),
       overlay_apk_path_(overlay_apk_path),
       target_apk_path_(target_apk_path),
-      idmap_last_mod_time_(getFileModDate(idmap_path_.data())) {}
+      idmap_last_mod_time_(getFileModDate(idmap_fd_.get())) {}
 
 std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPiece idmap_data) {
   ATRACE_CALL();
@@ -368,7 +375,7 @@
 }
 
 bool LoadedIdmap::IsUpToDate() const {
-  return idmap_last_mod_time_ == getFileModDate(idmap_path_.c_str());
+  return idmap_last_mod_time_ == getFileModDate(idmap_fd_.get());
 }
 
 }  // namespace android
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 2c99f1a..a3dd983 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -54,6 +54,8 @@
 #define INT32_MAX ((int32_t)(2147483647))
 #endif
 
+using namespace std::literals;
+
 namespace android {
 
 #if defined(_WIN32)
@@ -237,12 +239,24 @@
     fill9patchOffsets(reinterpret_cast<Res_png_9patch*>(outData));
 }
 
-bool IsFabricatedOverlay(const std::string& path) {
-  return IsFabricatedOverlay(path.c_str());
+bool IsFabricatedOverlayName(std::string_view path) {
+  static constexpr auto suffixFrro = ".frro"sv;
+  static constexpr auto suffixIdmap = ".frro@idmap"sv;
+
+  return (path.size() > suffixFrro.size() && path.ends_with(suffixFrro))
+        || (path.size() > suffixIdmap.size() && path.ends_with(suffixIdmap));
 }
 
-bool IsFabricatedOverlay(const char* path) {
-  auto fd = base::unique_fd(base::utf8::open(path, O_RDONLY|O_CLOEXEC));
+bool IsFabricatedOverlay(std::string_view path) {
+  if (!IsFabricatedOverlayName(path)) {
+    return false;
+  }
+  std::string path_copy;
+  if (path[path.size()] != '\0') {
+    path_copy.assign(path);
+    path = path_copy;
+  }
+  auto fd = base::unique_fd(base::utf8::open(path.data(), O_RDONLY|O_CLOEXEC|O_BINARY));
   if (fd < 0) {
     return false;
   }
@@ -7319,9 +7333,6 @@
 public:
     void add(uint32_t targetResId, uint32_t overlayResId) {
         uint8_t targetTypeId = Res_GETTYPE(targetResId);
-        if (mData.find(targetTypeId) == mData.end()) {
-            mData.emplace(targetTypeId, std::set<std::pair<uint32_t, uint32_t>>());
-        }
         auto& entries = mData[targetTypeId];
         entries.insert(std::make_pair(targetResId, overlayResId));
     }
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index d9f7c2a..c32a38e 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -23,6 +23,7 @@
 #include <variant>
 
 #include "android-base/macros.h"
+#include "android-base/unique_fd.h"
 #include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "androidfw/ResourceTypes.h"
@@ -159,11 +160,6 @@
   // Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed.
   static std::unique_ptr<LoadedIdmap> Load(StringPiece idmap_path, StringPiece idmap_data);
 
-  // Returns the path to the IDMAP.
-  std::string_view IdmapPath() const {
-    return idmap_path_;
-  }
-
   // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated.
   std::string_view OverlayApkPath() const {
     return overlay_apk_path_;
@@ -203,7 +199,7 @@
   const Idmap_overlay_entry* overlay_entries_;
   const std::unique_ptr<ResStringPool> string_pool_;
 
-  std::string idmap_path_;
+  android::base::unique_fd idmap_fd_;
   std::string_view overlay_apk_path_;
   std::string_view target_apk_path_;
   time_t idmap_last_mod_time_;
@@ -211,7 +207,7 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
 
-  explicit LoadedIdmap(std::string&& idmap_path,
+  explicit LoadedIdmap(const std::string& idmap_path,
                        const Idmap_header* header,
                        const Idmap_data_header* data_header,
                        const Idmap_target_entry* target_entries,
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 3d1403d..c264890 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -59,8 +59,8 @@
 constexpr const uint32_t kFabricatedOverlayCurrentVersion = 3;
 
 // Returns whether or not the path represents a fabricated overlay.
-bool IsFabricatedOverlay(const std::string& path);
-bool IsFabricatedOverlay(const char* path);
+bool IsFabricatedOverlayName(std::string_view path);
+bool IsFabricatedOverlay(std::string_view path);
 bool IsFabricatedOverlay(android::base::borrowed_fd fd);
 
 /**
diff --git a/libs/androidfw/include/androidfw/misc.h b/libs/androidfw/include/androidfw/misc.h
index d40d24e..077609d 100644
--- a/libs/androidfw/include/androidfw/misc.h
+++ b/libs/androidfw/include/androidfw/misc.h
@@ -43,6 +43,8 @@
 FileType getFileType(const char* fileName);
 /* get the file's modification date; returns -1 w/errno set on failure */
 time_t getFileModDate(const char* fileName);
+/* same, but also returns -1 if the file has already been deleted */
+time_t getFileModDate(int fd);
 
 // Check if |path| or |fd| resides on a readonly filesystem.
 bool isReadonlyFilesystem(const char* path);
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
index d3949e9..93dcaf5 100644
--- a/libs/androidfw/misc.cpp
+++ b/libs/androidfw/misc.cpp
@@ -76,13 +76,23 @@
 /*
  * Get a file's modification date.
  */
-time_t getFileModDate(const char* fileName)
-{
+time_t getFileModDate(const char* fileName) {
     struct stat sb;
+    if (stat(fileName, &sb) < 0) {
+        return (time_t)-1;
+    }
+    return sb.st_mtime;
+}
 
-    if (stat(fileName, &sb) < 0)
-        return (time_t) -1;
-
+time_t getFileModDate(int fd) {
+    struct stat sb;
+    if (fstat(fd, &sb) < 0) {
+        return (time_t)-1;
+    }
+    if (sb.st_nlink <= 0) {
+        errno = ENOENT;
+        return (time_t)-1;
+    }
     return sb.st_mtime;
 }
 
diff --git a/media/lib/tvremote/tests/Android.bp b/media/lib/tvremote/tests/Android.bp
index f02cfc3..280c515 100644
--- a/media/lib/tvremote/tests/Android.bp
+++ b/media/lib/tvremote/tests/Android.bp
@@ -17,6 +17,7 @@
     ],
     static_libs: [
         "mockito-target-minus-junit4",
+        "androidx.test.rules",
     ],
     platform_apis: true,
     certificate: "platform",
diff --git a/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java b/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java
index e6e3939..3b38a462 100644
--- a/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java
+++ b/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java
@@ -29,7 +29,8 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import java.util.ArrayList;
 
diff --git a/media/mca/tests/Android.bp b/media/mca/tests/Android.bp
index f02b4c0..04f083d 100644
--- a/media/mca/tests/Android.bp
+++ b/media/mca/tests/Android.bp
@@ -13,7 +13,10 @@
         "android.test.runner",
         "android.test.base",
     ],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+    ],
     // Include all test java files.
     srcs: ["src/**/*.java"],
     platform_apis: true,
diff --git a/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java b/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java
index 474b00f..44f98050 100644
--- a/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java
+++ b/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java
@@ -16,18 +16,19 @@
 
 package android.camera.mediaeffects.tests.functional;
 
-import android.media.filterfw.samples.CameraEffectsRecordingSample;
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Intent;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-import android.util.Log;
-import android.content.Intent;
-import android.os.Environment;
 import android.media.MediaMetadataRetriever;
+import android.media.filterfw.samples.CameraEffectsRecordingSample;
 import android.net.Uri;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import androidx.test.filters.LargeTest;
+
 import java.io.File;
 
 public class EffectsVideoCapture extends ActivityInstrumentationTestCase2
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
index 9b643ad..022f1da 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
@@ -16,9 +16,6 @@
 
 package com.android.mediaframeworktest.functional;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-
 import android.content.Context;
 import android.hardware.Camera;
 import android.hardware.Camera.PictureCallback;
@@ -27,10 +24,14 @@
 import android.os.ConditionVariable;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.view.SurfaceHolder;
 
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+
 import java.io.*;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
index da106be..8f32e91 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
@@ -18,9 +18,10 @@
 
 import android.media.MediaMetadataRetriever;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.util.Log;
 
+import androidx.test.filters.MediumTest;
+
 import com.android.mediaframeworktest.MediaNames;
 import com.android.mediaframeworktest.MediaProfileReader;
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
index 728e68d..83793ee 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
@@ -16,21 +16,20 @@
 
 package com.android.mediaframeworktest.functional;
 
-import java.io.File;
-
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.filters.Suppress;
+
 import com.android.mediaframeworktest.MediaFrameworkTest;
 
+import java.io.File;
+
 /*
  * System tests for the handling of mime type in the media framework.
  *
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
index 55a1545..d7d1875 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
@@ -16,17 +16,14 @@
 
 package com.android.mediaframeworktest.functional;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
 import android.media.MediaPlayer;
 import android.os.Parcel;
+import android.test.ActivityInstrumentationTestCase2;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.filters.Suppress;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 import java.util.Calendar;
 import java.util.Random;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java
index ab78714..6b8cbe9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java
@@ -16,28 +16,26 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
 import android.media.AudioFormat;
 import android.media.AudioManager;
-import android.media.AudioTrack;
 import android.media.AudioRecord;
-import android.media.audiofx.EnvironmentalReverb;
-import android.media.audiofx.Equalizer;
+import android.media.AudioTrack;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
-
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.EnvironmentalReverb;
+import android.media.audiofx.Equalizer;
 import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.UUID;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
index 3a332c6..25288e1 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
@@ -16,16 +16,16 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
 import android.content.Context;
 import android.media.AudioManager;
-import android.media.MediaPlayer;
 import android.media.AudioManager.OnAudioFocusChangeListener;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.MediumTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 /**
  * Junit / Instrumentation test case for the media AudioManager api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java
index eac5c28..107b51d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java
@@ -16,17 +16,15 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioTrack;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 /**
  * Junit / Instrumentation test case for the media AudioTrack api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java
index 1fa5c0d..c2dd246 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java
@@ -16,27 +16,13 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.functional.EnergyProbe;
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
-import android.media.AudioManager;
 import android.media.audiofx.BassBoost;
-import android.media.audiofx.Visualizer;
-import android.media.MediaPlayer;
-
-import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.util.UUID;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 /**
  * Junit / Instrumentation test case for the media AudioTrack api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
index e788c17..4bbd913 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
@@ -16,26 +16,20 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.functional.EnergyProbe;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
 import android.media.AudioManager;
-import android.media.audiofx.EnvironmentalReverb;
-import android.media.audiofx.Visualizer;
 import android.media.MediaPlayer;
-
-import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.EnvironmentalReverb;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.functional.EnergyProbe;
+
 import java.util.UUID;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java
index da9089d..a43f761 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java
@@ -16,27 +16,13 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.functional.EnergyProbe;
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
-import android.media.AudioManager;
 import android.media.audiofx.Equalizer;
-import android.media.audiofx.Visualizer;
-import android.media.MediaPlayer;
-
-import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.util.UUID;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 /**
  * Junit / Instrumentation test case for the media AudioTrack api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
index bc9c48d..9d3cf79 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
@@ -16,26 +16,20 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.functional.EnergyProbe;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
 import android.media.AudioManager;
-import android.media.audiofx.PresetReverb;
-import android.media.audiofx.Visualizer;
 import android.media.MediaPlayer;
-
-import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.PresetReverb;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.functional.EnergyProbe;
+
 import java.util.UUID;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java
index 122545f..144656c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java
@@ -16,27 +16,13 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.functional.EnergyProbe;
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
-import android.media.AudioManager;
 import android.media.audiofx.Virtualizer;
-import android.media.audiofx.Visualizer;
-import android.media.MediaPlayer;
-
-import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.util.UUID;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 
 /**
  * Junit / Instrumentation test case for the media AudioTrack api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
index abf85d7..7644954 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
@@ -16,24 +16,20 @@
 
 package com.android.mediaframeworktest.functional.audio;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.media.audiofx.AudioEffect;
 import android.media.AudioManager;
-import android.media.audiofx.Visualizer;
 import android.media.MediaPlayer;
-
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.Visualizer;
 import android.os.Looper;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+
 import java.util.UUID;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java
index aaf992c..ae42074 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java
@@ -17,12 +17,13 @@
 package com.android.mediaframeworktest.functional.audio;
 
 // import android.content.Resources;
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.functional.TonesAutoTest;
-
 import android.content.Context;
 import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.functional.TonesAutoTest;
 
 /**
  * Junit / Instrumentation test case for the SIM tone generator
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
index 9c08d48..bf5e816 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
@@ -16,22 +16,23 @@
 
 package com.android.mediaframeworktest.functional.camera;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.helpers.CameraTestHelper;
-
-import java.io.Writer;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.List;
-
 import android.hardware.Camera.Parameters;
 import android.os.Handler;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.view.SurfaceHolder;
 
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.helpers.CameraTestHelper;
+
+import java.io.Writer;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Junit / Instrumentation test case for the following camera APIs:
  * - flash
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
index f9d4964..45c95e0 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
@@ -20,17 +20,18 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.view.SurfaceHolder;
 
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.List;
+import androidx.test.filters.LargeTest;
 
 import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.helpers.CameraTestHelper;
 
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Junit / Instrumentation test case for camera API pairwise testing
  * Settings tested against: flash mode, exposure compensation, white balance,
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
index 7be2707..8739820 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java
@@ -16,20 +16,18 @@
 
 package com.android.mediaframeworktest.functional.mediaplayback;
 
+import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.MediumTest;
+
 import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.MediaNames;
 import com.android.mediaframeworktest.MediaProfileReader;
 import com.android.mediaframeworktest.functional.CodecTest;
 
-import android.content.Context;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.io.File;
-
 /**
  * Junit / Instrumentation test case for the media player api
  */
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
index 35540e3..3c456fb 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
@@ -16,37 +16,32 @@
 
 package com.android.mediaframeworktest.functional.mediarecorder;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaNames;
-
-import java.io.*;
-
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.Typeface;
 import android.hardware.Camera;
+import android.media.EncoderCapabilities.AudioEncoderCap;
+import android.media.EncoderCapabilities.VideoEncoderCap;
 import android.media.MediaCodec;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
-import android.media.EncoderCapabilities;
-import android.media.EncoderCapabilities.VideoEncoderCap;
-import android.media.EncoderCapabilities.AudioEncoderCap;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import com.android.mediaframeworktest.MediaProfileReader;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.MediaFrameworkTestRunner;
+import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaProfileReader;
 
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
+import java.io.*;
 import java.util.List;
 
-
 /**
  * Junit / Instrumentation test case for the media recorder api
  */
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index cc7a7d5..e89becd 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -31,9 +31,10 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import androidx.test.filters.SmallTest;
+
 /**
  * <p>
  * Junit / Instrumentation test case for the camera2 api
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 9d09dcc..eaa5a85 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -46,10 +46,11 @@
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.view.Surface;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
 
 import org.mockito.ArgumentCaptor;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 8c05725..0154d6a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -16,36 +16,33 @@
 
 package com.android.mediaframeworktest.performance;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner;
-import com.android.mediaframeworktest.MediaNames;
-import com.android.mediaframeworktest.MediaTestUtil;
-
-import android.database.sqlite.SQLiteDatabase;
 import android.hardware.Camera;
 import android.hardware.Camera.PreviewCallback;
 import android.media.CamcorderProfile;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
-import android.media.EncoderCapabilities.VideoEncoderCap;
 import android.os.ConditionVariable;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.view.SurfaceHolder;
 
-import java.util.List;
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner;
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaProfileReader;
+import com.android.mediaframeworktest.MediaTestUtil;
+
 import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Writer;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-
-import com.android.mediaframeworktest.MediaProfileReader;
 
 /**
  * Junit / Instrumentation - performance measurement for media player and
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
index dc8da48..a47d8bc 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java
@@ -43,13 +43,13 @@
 import android.media.MediaFormat;
 import android.media.MediaRecorder;
 import android.os.SystemClock;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.util.Range;
 import android.util.Size;
 import android.view.Surface;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
 
 import com.android.ex.camera2.blocking.BlockingSessionCallback;
 import com.android.mediaframeworktest.Camera2SurfaceViewTestCase;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java
index a26ee2d..002a143 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java
@@ -16,71 +16,34 @@
 
 package com.android.mediaframeworktest.stress;
 
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-import com.android.mediaframeworktest.Camera2SurfaceViewTestCase;
-import com.android.mediaframeworktest.helpers.Camera2Focuser;
-import com.android.mediaframeworktest.helpers.CameraTestUtils;
-import com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback;
-
-import android.graphics.ImageFormat;
-import android.graphics.Point;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.DngCreator;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.media.Image;
-import android.media.ImageReader;
-import android.media.CamcorderProfile;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
-import android.media.MediaRecorder;
-import android.os.ConditionVariable;
-import android.os.Environment;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Rational;
-import android.util.Size;
-import android.view.Surface;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.util.Range;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS;
 import static com.android.mediaframeworktest.helpers.CameraTestUtils.MAX_READER_IMAGES;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.basicValidateJpegImage;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.dumpFile;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.getValueNotNull;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.makeImageReader;
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.SESSION_CLOSED;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS;
-import static com.android.mediaframeworktest.helpers.CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS;
 import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_1080P;
 import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_2160P;
+import static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener;
+import static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession;
 import static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedVideoSizes;
 
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.media.CamcorderProfile;
+import android.media.ImageReader;
+import android.media.MediaRecorder;
+import android.util.Log;
+import android.util.Range;
+import android.util.Size;
+import android.view.Surface;
+
 import com.android.ex.camera2.blocking.BlockingSessionCallback;
 import com.android.mediaframeworktest.Camera2SurfaceViewTestCase;
-import com.android.mediaframeworktest.helpers.CameraTestUtils;
+import com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback;
 
-import junit.framework.AssertionFailedError;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
 
 /**
  * <p>Tests Back/Front camera switching and Camera/Video modes witching.</p>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
index 74244b9..9883df2e3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
@@ -16,6 +16,16 @@
 
 package com.android.mediaframeworktest.stress;
 
+import android.hardware.Camera.Parameters;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
 import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.helpers.CameraTestHelper;
 
@@ -23,19 +33,9 @@
 import java.io.File;
 import java.io.FileWriter;
 import java.io.Writer;
+import java.util.List;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
-import java.util.List;
-
-import android.hardware.Camera.Parameters;
-import android.os.Handler;
-import android.os.Looper;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import androidx.test.InstrumentationRegistry;
 
 /**
  * Junit / Instrumentation test case for the following camera APIs:
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
index 6a820ec..cb69e1b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
@@ -16,16 +16,16 @@
 
 package com.android.mediaframeworktest.stress;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
-
 import android.os.Bundle;
 import android.os.Environment;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
 import com.android.mediaframeworktest.functional.CodecTest;
 
 import java.io.BufferedReader;
@@ -34,7 +34,6 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.Writer;
-
 import java.util.ArrayList;
 import java.util.List;
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index 4221f1b..221881a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -16,16 +16,16 @@
 
 package com.android.mediaframeworktest.stress;
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
-
 import android.os.Bundle;
 import android.os.Environment;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
 import com.android.mediaframeworktest.functional.CodecTest;
 
 import java.io.BufferedWriter;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 199f179..47bd633 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -17,16 +17,6 @@
 package com.android.mediaframeworktest.stress;
 
 
-import com.android.mediaframeworktest.MediaFrameworkTest;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
 import android.hardware.Camera;
 import android.media.CamcorderProfile;
 import android.media.MediaPlayer;
@@ -35,11 +25,22 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 import android.view.SurfaceHolder;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
 import com.android.mediaframeworktest.MediaRecorderStressTestRunner;
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Junit / Instrumentation test case for the media player api
  */
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java
index 6c2a3f7..fec108f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java
@@ -20,9 +20,10 @@
 import android.media.MediaPlayer;
 import android.os.Bundle;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+
 import com.android.mediaframeworktest.AudioTestHarnessTemplateRunner;
 import com.android.mediaframeworktest.MediaFrameworkTest;
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
index c814eba..964da45 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -16,12 +16,10 @@
 
 package com.android.mediaframeworktest.unit;
 
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Range;
-import android.util.Rational;
-import android.util.SizeF;
+import static android.hardware.camera2.impl.CameraMetadataNative.*;
+
+import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*;
+
 import android.graphics.ImageFormat;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -31,7 +29,6 @@
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
-import android.util.Size;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
 import android.hardware.camera2.params.ColorSpaceTransform;
@@ -45,9 +42,14 @@
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.params.TonemapCurve;
 import android.hardware.camera2.utils.TypeReference;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
+import android.util.SizeF;
 
-import static android.hardware.camera2.impl.CameraMetadataNative.*;
-import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*;
+import androidx.test.filters.SmallTest;
 
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java
index 1b765ea..924ad47 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java
@@ -20,8 +20,7 @@
 
 import android.hardware.camera2.utils.TypeReference;
 
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
+import androidx.test.filters.SmallTest;
 
 import java.lang.reflect.Type;
 import java.util.List;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java
index b648763..6cb8b54 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java
@@ -18,7 +18,8 @@
 
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.utils.UncheckedThrow;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import junit.framework.Assert;
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
index 2cb5704..d9fc88d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java
@@ -24,7 +24,8 @@
 import android.media.ImageReader;
 import android.media.ImageReader.OnImageAvailableListener;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 public class ImageReaderTest extends AndroidTestCase {
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index ea0494f..65264d3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -36,7 +36,8 @@
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Video;
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index e3d3897..80edf8a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -26,10 +26,10 @@
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.util.Log;
 
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.media.playback.flags.Flags;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
index 37dd4b5..06c527d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
index 48fd16c..5a36044 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java
index 6d3c083..f86f77e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java
index 198439c..fb31edb3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java
index b9c63fd..e1c992e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java
index bfa3976..7aed3b7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java
@@ -18,10 +18,9 @@
 import android.media.Metadata;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
 
-import java.util.Calendar;
+import androidx.test.filters.SmallTest;
+
 import java.util.Date;
 
 /*
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
index 7a96792..aa4bfe6 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java
index 2497cd7..d8651f5 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
index 991fe9c..3bcde7f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
index b984514..36e93c0 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java
@@ -16,10 +16,11 @@
 
 package com.android.mediaframeworktest.unit;
 
-import android.media.MediaPlayer;
 import android.media.AudioManager;
+import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java
index 17c9d8c..adb56d0f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java
index a149565..84691da 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
index 68c8e42..a0999d8 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
index ab8519a..b0673a8 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java
@@ -18,7 +18,8 @@
 
 import android.media.MediaPlayer;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.filters.LargeTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
index 134144d..8299a7e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
@@ -18,8 +18,9 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
+
 import java.io.IOException;
 
 /**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
index cae9e31..1e4c060 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
index 4b5a818..b3e9009d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
index f8ab48cf..3b56e6f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
index 712a758..0980802 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
index cacdd87..3a4a7c7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
index d1232fc..192c896 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
@@ -18,8 +18,8 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
+
+import androidx.test.filters.MediumTest;
 
 /**
  * Unit test class to test the set of valid and invalid states that
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
index 91100ae..093ed88 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
@@ -18,10 +18,10 @@
 
 import android.media.MediaRecorder;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
+import androidx.test.filters.MediumTest;
+
 /**
  * Unit test class to test the set of valid and invalid states that
  * MediaRecorder.stop() method can be called.
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java
index 9dd2732..f54f06d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java
@@ -16,10 +16,11 @@
 
 package com.android.mediaframeworktest.unit;
 
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Range;
 import android.util.Rational;
 
+import androidx.test.filters.SmallTest;
+
 /**
  * <pre>
  * adb shell am instrument \
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
index 1bb7db9..a94b5af 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -16,9 +16,12 @@
 
 package com.android.mediaframeworktest.unit;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import static android.util.Rational.*;
+
 import android.util.Rational;
 
+import androidx.test.filters.SmallTest;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -28,8 +31,6 @@
 import java.io.Serializable;
 import java.lang.reflect.Field;
 
-import static android.util.Rational.*;
-
 /**
  * <pre>
  * adb shell am instrument \
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java
index f578e46..cd564b2 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java
@@ -19,9 +19,10 @@
 import android.graphics.ImageFormat;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.media.ImageReader;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.Surface;
 
+import androidx.test.filters.SmallTest;
+
 import junit.framework.Assert;
 
 public class SurfaceUtilsTest extends junit.framework.TestCase {
diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp
index c9a8864..fd5f195 100644
--- a/media/tests/projection/Android.bp
+++ b/media/tests/projection/Android.bp
@@ -3,6 +3,7 @@
 //########################################################################
 
 package {
+    default_team: "trendy_team_lse_desktop_os_experience",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "frameworks_base_license"
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.java b/nfc/java/android/nfc/cardemulation/PollingFrame.java
index 3383f3b..994f4ae 100644
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.java
+++ b/nfc/java/android/nfc/cardemulation/PollingFrame.java
@@ -201,7 +201,7 @@
 
     /**
      * Returns the timestamp of when the polling loop frame was observed in milliseconds. These
-     * timestamps are relative and not absolute and should only be used fro comparing the timing of
+     * timestamps are relative and not absolute and should only be used for comparing the timing of
      * frames relative to each other.
      * @return the timestamp in milliseconds
      */
diff --git a/packages/CredentialManager/res/values/dimens.xml b/packages/CredentialManager/res/values/dimens.xml
index 350920b2..82dee5c 100644
--- a/packages/CredentialManager/res/values/dimens.xml
+++ b/packages/CredentialManager/res/values/dimens.xml
@@ -26,7 +26,7 @@
     <dimen name="autofill_dropdown_textview_min_width">112dp</dimen>
     <dimen name="autofill_dropdown_textview_max_width">230dp</dimen>
     <dimen name="dropdown_layout_horizontal_margin">24dp</dimen>
-    <integer name="autofill_max_visible_datasets">5</integer>
+    <integer name="autofill_max_visible_datasets">4</integer>
     <dimen name="dropdown_touch_target_min_height">48dp</dimen>
     <dimen name="horizontal_chip_padding">8dp</dimen>
     <dimen name="vertical_chip_padding">6dp</dimen>
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
index 39d3f42..e2857f9 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt
@@ -47,8 +47,9 @@
 import com.android.credentialmanager.model.get.ProviderInfo
 import com.android.credentialmanager.model.get.RemoteEntryInfo
 import com.android.credentialmanager.TAG
+import com.android.credentialmanager.model.EntryInfo
 
-fun CredentialEntryInfo.getIntentSenderRequest(
+fun EntryInfo.getIntentSenderRequest(
     isAutoSelected: Boolean = false
 ): IntentSenderRequest? {
     val entryIntent = fillInIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected)
@@ -132,6 +133,7 @@
                     lastUsedTimeMillis = credentialEntry.lastUsedTime,
                     isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
                             credentialEntry.isAutoSelectAllowedFromOption,
+                    entryGroupId = credentialEntry.entryGroupId.toString(),
                 )
                 )
             }
@@ -155,6 +157,7 @@
                     lastUsedTimeMillis = credentialEntry.lastUsedTime,
                     isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
                             credentialEntry.isAutoSelectAllowedFromOption,
+                    entryGroupId = credentialEntry.entryGroupId.toString(),
                 )
                 )
             }
@@ -177,6 +180,7 @@
                     lastUsedTimeMillis = credentialEntry.lastUsedTime,
                     isAutoSelectable = credentialEntry.isAutoSelectAllowed &&
                             credentialEntry.isAutoSelectAllowedFromOption,
+                    entryGroupId = credentialEntry.entryGroupId.toString(),
                 )
                 )
             }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
index 9725881..a5d4730 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt
@@ -40,6 +40,8 @@
     val shouldTintIcon: Boolean,
     val lastUsedTimeMillis: Instant?,
     val isAutoSelectable: Boolean,
+    val entryGroupId: String, // Used for deduplication, and displayed as the grouping title
+                              // "For <value-of-entryGroupId>" on the more-option screen.
 ) : EntryInfo(
     providerId,
     entryKey,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 1326023..293e111 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -237,23 +237,14 @@
         if (providerList.isEmpty()) {
             return false
         }
-        var totalEntryCount = 0
-        providerList.forEach { provider ->
-            totalEntryCount += provider.credentialEntryList.size
-        }
         val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerList)
+        var totalEntryCount = providerDisplayInfo.sortedUserNameToCredentialEntryList.size
         val inlineSuggestionsRequest = filLRequest.inlineSuggestionsRequest
-        val inlineMaxSuggestedCount = inlineSuggestionsRequest?.maxSuggestionCount ?: 0
         val inlinePresentationSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs
         val inlinePresentationSpecsCount = inlinePresentationSpecs?.size ?: 0
-        val maxDropdownDisplayLimit = this.resources.getInteger(
+        val maxDatasetDisplayLimit = this.resources.getInteger(
                 com.android.credentialmanager.R.integer.autofill_max_visible_datasets)
-        var maxInlineItemCount = totalEntryCount
-        maxInlineItemCount = maxInlineItemCount.coerceAtMost(inlineMaxSuggestedCount)
-        val lastDropdownDatasetIndex = Settings.Global.getInt(this.contentResolver,
-                Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
-                (maxDropdownDisplayLimit - 1)).coerceAtMost(totalEntryCount)
-
+                .coerceAtMost(totalEntryCount)
         var i = 0
         var datasetAdded = false
 
@@ -278,7 +269,7 @@
                 Log.e(TAG, "PendingIntent was missing from the entry.")
                 return@usernameLoop
             }
-            if (i >= maxInlineItemCount && i >= lastDropdownDatasetIndex) {
+            if (i >= maxDatasetDisplayLimit) {
                 return@usernameLoop
             }
             val icon: Icon = if (primaryEntry.icon == null) {
@@ -291,7 +282,7 @@
             }
             // Create inline presentation
             var inlinePresentation: InlinePresentation? = null
-            if (inlinePresentationSpecs != null && i < maxInlineItemCount) {
+            if (inlinePresentationSpecs != null && i < maxDatasetDisplayLimit) {
                 val spec: InlinePresentationSpec? = if (i < inlinePresentationSpecsCount) {
                     inlinePresentationSpecs[i]
                 } else {
@@ -305,7 +296,7 @@
                 }
             }
             var dropdownPresentation: RemoteViews? = null
-            if (i < lastDropdownDatasetIndex) {
+            if (i < maxDatasetDisplayLimit) {
                 dropdownPresentation = RemoteViewsFactory
                         .createDropdownPresentation(this, icon, primaryEntry)
             }
@@ -331,17 +322,15 @@
                             .build())
             datasetAdded = true
             i++
-
-            if (i == lastDropdownDatasetIndex) {
-                addDropdownMoreOptionsPresentation(bottomSheetIntent, autofillId,
-                        fillResponseBuilder)
-            }
         }
         val pinnedSpec = getLastInlinePresentationSpec(inlinePresentationSpecs,
                 inlinePresentationSpecsCount)
-        if (datasetAdded && pinnedSpec != null) {
-            addPinnedInlineSuggestion(pinnedSpec, autofillId,
-                    fillResponseBuilder, bottomSheetIntent)
+        if (datasetAdded) {
+            addDropdownMoreOptionsPresentation(bottomSheetIntent, autofillId, fillResponseBuilder)
+            if (pinnedSpec != null) {
+                addPinnedInlineSuggestion(pinnedSpec, autofillId,
+                        fillResponseBuilder, bottomSheetIntent)
+            }
         }
         return datasetAdded
     }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index d24adb5..4ef7760 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -16,6 +16,7 @@
 
 package com.android.credentialmanager.createflow
 
+import android.credentials.flags.Flags.selectorUiImprovementsEnabled
 import android.text.TextUtils
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
@@ -329,6 +330,18 @@
             )
         }
         item { Divider(thickness = 24.dp, color = Color.Transparent) }
+
+        val footerDescription = createOptionInfo.footerDescription
+        if (selectorUiImprovementsEnabled()) {
+            if (!footerDescription.isNullOrBlank()) {
+                item {
+                    Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+                        BodySmallText(text = footerDescription)
+                    }
+                }
+                item { Divider(thickness = 24.dp, color = Color.Transparent) }
+            }
+        }
         item {
             CredentialContainerCard {
                 PrimaryCreateOptionRow(
@@ -366,18 +379,19 @@
                 },
             )
         }
-        val footerDescription = createOptionInfo.footerDescription
-        if (footerDescription != null && footerDescription.length > 0) {
-            item {
-                Divider(
-                    thickness = 1.dp,
-                    color = LocalAndroidColorScheme.current.outlineVariant,
-                    modifier = Modifier.padding(vertical = 16.dp)
-                )
-            }
-            item {
-                Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
-                    BodySmallText(text = footerDescription)
+        if (!selectorUiImprovementsEnabled()) {
+            if (footerDescription != null && footerDescription.length > 0) {
+                item {
+                    Divider(
+                        thickness = 1.dp,
+                        color = LocalAndroidColorScheme.current.outlineVariant,
+                        modifier = Modifier.padding(vertical = 16.dp)
+                    )
+                }
+                item {
+                    Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
+                        BodySmallText(text = footerDescription)
+                    }
                 }
             }
         }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 458a99a..e7f11a1 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.credentialmanager.getflow
 
+import android.credentials.flags.Flags.selectorUiImprovementsEnabled
 import android.graphics.drawable.Drawable
 import com.android.credentialmanager.model.get.ProviderInfo
 import com.android.credentialmanager.model.EntryInfo
@@ -133,7 +134,7 @@
 
         providerInfo.credentialEntryList.forEach {
             userNameToCredentialEntryMap.compute(
-                it.userName
+                if (selectorUiImprovementsEnabled()) it.entryGroupId else it.userName
             ) { _, v ->
                 if (v == null) {
                     mutableListOf(it)
diff --git a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
index e609d0c..d9ba36e 100644
--- a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
+++ b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt
@@ -146,7 +146,8 @@
                                 icon = null,
                                 shouldTintIcon = true,
                                 lastUsedTimeMillis = null,
-                                isAutoSelectable = false
+                                isAutoSelectable = false,
+                                entryGroupId = "username",
                         )
                 ),
                 authenticationEntryList = emptyList(),
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 463c4d1..66be7ba 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -29,10 +29,14 @@
 import com.android.credentialmanager.model.get.CredentialEntryInfo
 import com.android.credentialmanager.ui.mappers.toGet
 import android.util.Log
+import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.compose.runtime.Composable
 import com.android.credentialmanager.CredentialSelectorUiState.Cancel
 import com.android.credentialmanager.CredentialSelectorUiState.Close
 import com.android.credentialmanager.CredentialSelectorUiState.Create
 import com.android.credentialmanager.CredentialSelectorUiState.Idle
+import com.android.credentialmanager.activity.StartBalIntentSenderForResultContract
+import com.android.credentialmanager.ktx.getIntentSenderRequest
 import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
@@ -47,6 +51,8 @@
 ) : FlowEngine, ViewModel() {
     private val isPrimaryScreen = MutableStateFlow(true)
     private val shouldClose = MutableStateFlow(false)
+    private lateinit var selectedEntry: EntryInfo
+    private var isAutoSelected: Boolean = false
     val uiState: StateFlow<CredentialSelectorUiState> =
         combine(
             credentialManagerClient.requests,
@@ -108,6 +114,25 @@
         )
         shouldClose.value = result
     }
+
+    @Composable
+    override fun getEntrySelector(): (entry: EntryInfo, isAutoSelected: Boolean) -> Unit {
+        val launcher = rememberLauncherForActivityResult(
+            StartBalIntentSenderForResultContract()
+        ) {
+            sendSelectionResult(entryInfo = selectedEntry,
+                resultCode = it.resultCode,
+                resultData = it.data,
+                isAutoSelected = isAutoSelected)
+        }
+        return { selected, autoSelect ->
+            selectedEntry = selected
+            isAutoSelected = autoSelect
+            selected.getIntentSenderRequest()?.let {
+                launcher.launch(it)
+            } ?: Log.w(TAG, "Cannot parse IntentSenderRequest")
+        }
+    }
 }
 
 sealed class CredentialSelectorUiState {
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
index e421644..2e80a7c 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt
@@ -17,6 +17,8 @@
 package com.android.credentialmanager
 
 import android.content.Intent
+import androidx.activity.result.IntentSenderRequest
+import androidx.compose.runtime.Composable
 import com.android.credentialmanager.model.EntryInfo
 
 /** Engine of the credential selecting flow. */
@@ -42,4 +44,14 @@
         resultData: Intent? = null,
         isAutoSelected: Boolean = false,
     )
+
+    /**
+     * Helper function to get an entry selector.
+     *
+     * @return selector fun consumes selected [EntryInfo]. Once invoked, [IntentSenderRequest] would
+     * be launched and invocation of [sendSelectionResult] would happen right after launching result
+     * coming back.
+     */
+    @Composable
+    fun getEntrySelector(): (entry: EntryInfo, isAutoSelected: Boolean) -> Unit
 }
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
index f9a58871..405de1d3 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt
@@ -43,6 +43,7 @@
 import com.google.android.horologist.compose.navscaffold.composable
 import com.google.android.horologist.compose.navscaffold.scrollable
 import com.android.credentialmanager.model.CredentialType
+import com.android.credentialmanager.model.EntryInfo
 import com.android.credentialmanager.ui.screens.multiple.MultiCredentialsFoldScreen
 
 @OptIn(ExperimentalHorologistApi::class)
@@ -56,6 +57,7 @@
     val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
     val navHostState =
         rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState)
+    val selectEntry = flowEngine.getEntrySelector()
 
     val uiState by viewModel.uiState.collectAsStateWithLifecycle()
     WearNavScaffold(
@@ -111,6 +113,7 @@
                 navController = navController,
                 state = state,
                 onCloseApp = onCloseApp,
+                selectEntry = selectEntry
             )
         }
 
@@ -133,9 +136,14 @@
     navController: NavController,
     state: CredentialSelectorUiState.Get,
     onCloseApp: () -> Unit,
+    selectEntry: (entry: EntryInfo, isAutoSelected: Boolean) -> Unit,
 ) {
     when (state) {
         is SingleEntry -> {
+            if (state.entry.isAutoSelectable) {
+                selectEntry(state.entry, true)
+                return
+            }
             when (state.entry.credentialType) {
                 CredentialType.UNKNOWN -> {
                     navController.navigateToSignInWithProviderScreen()
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
index 1f1a296..2ca8ef1 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt
@@ -18,8 +18,6 @@
 
 package com.android.credentialmanager.ui.screens.single.password
 
-import android.util.Log
-import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
@@ -28,9 +26,6 @@
 import androidx.compose.ui.unit.dp
 import com.android.credentialmanager.FlowEngine
 import com.android.credentialmanager.R
-import com.android.credentialmanager.TAG
-import com.android.credentialmanager.activity.StartBalIntentSenderForResultContract
-import com.android.credentialmanager.ktx.getIntentSenderRequest
 import com.android.credentialmanager.ui.components.PasswordRow
 import com.android.credentialmanager.ui.components.ContinueChip
 import com.android.credentialmanager.ui.components.DismissChip
@@ -57,11 +52,7 @@
     modifier: Modifier = Modifier,
     flowEngine: FlowEngine,
 ) {
-    val launcher = rememberLauncherForActivityResult(
-        StartBalIntentSenderForResultContract()
-    ) {
-        flowEngine.sendSelectionResult(entry, it.resultCode, it.data)
-    }
+    val selectEntry = flowEngine.getEntrySelector()
     SingleAccountScreen(
         headerContent = {
             SignInHeader(
@@ -80,11 +71,7 @@
     ) {
         item {
             Column {
-                ContinueChip {
-                    entry.getIntentSenderRequest()?.let {
-                        launcher.launch(it)
-                    } ?: Log.w(TAG, "Cannot parse IntentSenderRequest")
-                }
+                ContinueChip { selectEntry(entry, false) }
                 SignInOptionsChip{ flowEngine.openSecondaryScreen() }
                 DismissChip { flowEngine.cancel() }
             }
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index 5f5f1d5..5966c9f 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -5,6 +5,7 @@
 dsandler@android.com
 edgarwang@google.com
 evanlaird@google.com
+jiannan@google.com
 juliacr@google.com
 ykhung@google.com
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
index bb7e857..3acf075 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt
@@ -18,7 +18,6 @@
 
 import androidx.compose.foundation.clickable
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
 import com.android.settingslib.spa.framework.common.EntryMacro
@@ -107,14 +106,9 @@
 ) {
     val onClickWithLog = wrapOnClickWithLog(model.onClick)
     val enabled = model.enabled()
-    val modifier = remember(enabled) {
-        if (onClickWithLog != null) {
-            Modifier.clickable(
-                enabled = enabled,
-                onClick = onClickWithLog
-            )
-        } else Modifier
-    }
+    val modifier = if (onClickWithLog != null) {
+        Modifier.clickable(enabled = enabled, onClick = onClickWithLog)
+    } else Modifier
     EntryHighlight {
         BasePreference(
             title = model.title,
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java
index 2a5c43c..9ab17c4 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java
@@ -37,9 +37,10 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.UserHandle;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.settingslib.BaseTest;
 
 import org.mockito.ArgumentMatcher;
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
index 2522e95..ab28d06 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
@@ -41,9 +41,10 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.InputMethodInfo;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.settingslib.BaseTest;
 
 import org.mockito.ArgumentMatcher;
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 53f2caf..0c02f56 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -210,6 +210,7 @@
     <uses-permission android:name="android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS" />
     <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" />
     <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" />
+    <uses-permission android:name="android.permission.EMERGENCY_INSTALL_PACKAGES" />
     <!-- Permission required for processes that don't own the focused window to switch
          touch mode state -->
     <uses-permission android:name="android.permission.MODIFY_TOUCH_MODE_STATE" />
diff --git a/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java b/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java
index 51b7ba8..ad9eec7 100644
--- a/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java
+++ b/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java
@@ -15,10 +15,12 @@
  */
 package com.android.shell;
 
-import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
 import static com.android.shell.BugreportProgressService.isValid;
 
+import androidx.test.filters.SmallTest;
+
+import junit.framework.TestCase;
+
 @SmallTest
 public class UtilitiesTest extends TestCase {
 
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index ba77380..cb6894e 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -563,3 +563,10 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "media_controls_refactor"
+    namespace: "systemui"
+    description: "Refactors media code to follow the recommended architecture"
+    bug: "326408371"
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index b611e0a..36919d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -1052,32 +1052,6 @@
             biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(true)
             faceAuthenticateIsCalled()
         }
-    @Test
-    fun authFailedCallAfterAuthLockedOutErrorShouldBeIgnored() =
-        testScope.runTest {
-            initCollectors()
-            allPreconditionsToRunFaceAuthAreTrue()
-            runCurrent()
-            assertThat(canFaceAuthRun()).isTrue()
-
-            underTest.requestAuthenticate(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED, false)
-            runCurrent()
-
-            faceAuthenticateIsCalled()
-            authenticationCallback.value.onAuthenticationError(
-                FACE_ERROR_LOCKOUT_PERMANENT,
-                "Too many attempts, face not available"
-            )
-
-            val lockoutError = authStatus() as ErrorFaceAuthenticationStatus
-            assertThat(lockedOut()).isTrue()
-            assertThat(lockoutError.isLockoutError()).isTrue()
-
-            authenticationCallback.value.onAuthenticationFailed()
-            runCurrent()
-
-            assertThat(authStatus()).isEqualTo(lockoutError)
-        }
 
     private suspend fun TestScope.testGatingCheckForFaceAuth(
         gatingCheckModifier: suspend () -> Unit
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index beaa708..e181d07 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -101,7 +101,7 @@
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling
+        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue
     </string>
 
     <!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index 7020d54..9036a35 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -222,6 +222,16 @@
         <item>On</item>
     </string-array>
 
+    <!-- State names for record_issue tile: unavailable, off, on.
+         This subtitle is shown when the tile is in that particular state but does not set its own
+         subtitle, so some of these may never appear on screen. They should still be translated as
+         if they could appear. [CHAR LIMIT=32] -->
+    <string-array name="tile_states_record_issue">
+        <item>Unavailable</item>
+        <item>Off</item>
+        <item>On</item>
+    </string-array>
+
     <!-- State names for reverse (charging) tile: unavailable, off, on.
          This subtitle is shown when the tile is in that particular state but does not set its own
          subtitle, so some of these may never appear on screen. They should still be translated as
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
index 363dd01..f528ec8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
@@ -18,11 +18,16 @@
 
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
+import android.hardware.biometrics.BiometricSourceType;
+import android.os.SystemClock;
 import android.text.Editable;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.util.Log;
+import android.util.Pair;
 import android.view.View;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -40,6 +45,16 @@
 public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
         extends ViewController<T> {
     /**
+     * Pair representing:
+     *   first - BiometricSource the currently displayed message is associated with.
+     *   second - Timestamp the biometric message came in uptimeMillis.
+     * This Pair can be null if the message is not associated with a biometric.
+     */
+    @Nullable
+    private Pair<BiometricSourceType, Long> mMessageBiometricSource = null;
+    private static final Long SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS = 3500L;
+
+    /**
      * Delay before speaking an accessibility announcement. Used to prevent
      * lift-to-type from interrupting itself.
      */
@@ -149,12 +164,42 @@
      * Sets a message to the underlying text view.
      */
     public void setMessage(CharSequence s, boolean animate) {
+        setMessage(s, animate, null);
+    }
+
+    /**
+     * Sets a message to the underlying text view.
+     */
+    public void setMessage(CharSequence s, BiometricSourceType biometricSourceType) {
+        setMessage(s, true, biometricSourceType);
+    }
+
+    private void setMessage(
+            CharSequence s,
+            boolean animate,
+            BiometricSourceType biometricSourceType) {
+        final long uptimeMillis = SystemClock.uptimeMillis();
+        if (skipShowingFaceMessage(biometricSourceType, uptimeMillis)) {
+            Log.d("KeyguardMessageAreaController", "Skip showing face message \"" + s + "\"");
+            return;
+        }
+        mMessageBiometricSource =  new Pair<>(biometricSourceType, uptimeMillis);
         if (mView.isDisabled()) {
             return;
         }
         mView.setMessage(s, animate);
     }
 
+    private boolean skipShowingFaceMessage(
+            BiometricSourceType biometricSourceType, Long currentUptimeMillis
+    ) {
+        return mMessageBiometricSource != null
+                && biometricSourceType == BiometricSourceType.FACE
+                && mMessageBiometricSource.first == BiometricSourceType.FINGERPRINT
+                && (currentUptimeMillis - mMessageBiometricSource.second)
+                    < SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS;
+    }
+
     public void setMessage(int resId) {
         String message = resId != 0 ? mView.getResources().getString(resId) : null;
         setMessage(message);
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index d2ad096..ce4032a 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -16,6 +16,7 @@
 
 package com.android.keyguard.logging
 
+import android.hardware.biometrics.BiometricSourceType
 import com.android.systemui.biometrics.AuthRippleController
 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController
 import com.android.systemui.log.LogBuffer
@@ -117,6 +118,26 @@
         )
     }
 
+    fun logDropNonFingerprintMessage(
+        message: CharSequence,
+        followUpMessage: CharSequence?,
+        biometricSourceType: BiometricSourceType?,
+    ) {
+        buffer.log(
+            KeyguardIndicationController.TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = message.toString()
+                str2 = followUpMessage?.toString()
+                str3 = biometricSourceType?.name
+            },
+            {
+                "droppingNonFingerprintMessage message=$str1 " +
+                    "followUpMessage:$str2 biometricSourceType:$str3"
+            }
+        )
+    }
+
     fun logUpdateBatteryIndication(
         powerIndication: String,
         pluggedIn: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 0bd44f0..f4cd5b9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -17,7 +17,6 @@
 package com.android.systemui.biometrics;
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.Flags.customBiometricPrompt;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;
@@ -33,6 +32,7 @@
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -402,7 +402,12 @@
             @Nullable FaceSensorPropertiesInternal faceProps,
             @NonNull VibratorHelper vibratorHelper
     ) {
-        if (Utils.isBiometricAllowed(config.mPromptInfo) || customBiometricPrompt()) {
+        // Set this value before showing either of the prompt.
+        mPromptSelectorInteractorProvider.get().setShouldShowBpWithoutIconForCredential(
+                config.mPromptInfo);
+
+        if (Utils.isBiometricAllowed(config.mPromptInfo)
+                || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) {
             addBiometricView(config, layoutInflater, viewModel, fpProps, faceProps, vibratorHelper);
         } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) {
             addCredentialView(true, false);
@@ -411,7 +416,6 @@
         }
     }
 
-
     private void addBiometricView(@NonNull Config config, @NonNull LayoutInflater layoutInflater,
             @NonNull PromptViewModel viewModel,
             @Nullable FingerprintSensorPropertiesInternal fpProps,
@@ -534,7 +538,8 @@
                 () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED));
         if (constraintBp()) {
             // Do nothing on attachment with constraintLayout
-        } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo) || customBiometricPrompt()) {
+        } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo)
+                || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) {
             mBiometricScrollView.addView(mBiometricView.asView());
         } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) {
             addCredentialView(true /* animatePanel */, false /* animateContents */);
@@ -819,6 +824,9 @@
 
         final Runnable endActionRunnable = () -> {
             setVisibility(View.INVISIBLE);
+            if (Flags.customBiometricPrompt()) {
+                mPromptSelectorInteractorProvider.get().resetPrompt();
+            }
             removeWindowIfAttached();
         };
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
index ad7bb0e..b87fadf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
@@ -16,8 +16,11 @@
 
 package com.android.systemui.biometrics.data.repository
 
+import android.hardware.biometrics.Flags
 import android.hardware.biometrics.PromptInfo
 import com.android.systemui.biometrics.AuthController
+import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed
 import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -65,6 +68,18 @@
      */
     val isConfirmationRequired: Flow<Boolean>
 
+    /**
+     * If biometric prompt without icon needs to show for displaying content prior to credential
+     * view.
+     */
+    val showBpWithoutIconForCredential: StateFlow<Boolean>
+
+    /**
+     * Update whether biometric prompt without icon needs to show for displaying content prior to
+     * credential view, which should be set before [setPrompt].
+     */
+    fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo)
+
     /** Update the prompt configuration, which should be set before [isShowing]. */
     fun setPrompt(
         promptInfo: PromptInfo,
@@ -129,6 +144,19 @@
             }
             .distinctUntilChanged()
 
+    private val _showBpWithoutIconForCredential: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow()
+
+    override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) {
+        val hasCredentialViewShown = kind.value !is PromptKind.Biometric
+        val showBpForCredential =
+            Flags.customBiometricPrompt() &&
+                !Utils.isBiometricAllowed(promptInfo) &&
+                isDeviceCredentialAllowed(promptInfo) &&
+                promptInfo.contentView != null
+        _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown
+    }
+
     override fun setPrompt(
         promptInfo: PromptInfo,
         userId: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
index e3facff..94cea57 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
@@ -30,6 +30,7 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
@@ -59,6 +60,13 @@
     /** If the prompt is currently showing. */
     val isShowing: Flow<Boolean> = biometricPromptRepository.isShowing
 
+    /**
+     * If biometric prompt without icon needs to show for displaying content prior to credential
+     * view.
+     */
+    val showBpWithoutIconForCredential: StateFlow<Boolean> =
+        biometricPromptRepository.showBpWithoutIconForCredential
+
     /** Metadata about the current credential prompt, including app-supplied preferences. */
     val prompt: Flow<BiometricPromptRequest.Credential?> =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
index b3f9574..45816c1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
@@ -70,6 +71,18 @@
     /** Fingerprint sensor type */
     val sensorType: Flow<FingerprintSensorType>
 
+    /**
+     * If biometric prompt without icon needs to show for displaying content prior to credential
+     * view.
+     */
+    val showBpWithoutIconForCredential: StateFlow<Boolean>
+
+    /**
+     * Update whether biometric prompt without icon needs to show for displaying content prior to
+     * credential view, which should be set before [PromptRepository.setPrompt].
+     */
+    fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo)
+
     /** Use biometrics for authentication. */
     fun useBiometricsForAuthentication(
         promptInfo: PromptInfo,
@@ -154,6 +167,12 @@
 
     override val sensorType: Flow<FingerprintSensorType> = fingerprintPropertyRepository.sensorType
 
+    override val showBpWithoutIconForCredential = promptRepository.showBpWithoutIconForCredential
+
+    override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) {
+        promptRepository.setShouldShowBpWithoutIconForCredential(promptInfo)
+    }
+
     override fun useBiometricsForAuthentication(
         promptInfo: PromptInfo,
         userId: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
index 6133a51c..6f079e2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
@@ -17,6 +17,7 @@
     val title: String,
     val subtitle: String,
     val description: String,
+    val contentView: PromptContentView?,
     val userInfo: BiometricUserInfo,
     val operationInfo: BiometricOperationInfo,
     val showEmergencyCallButton: Boolean,
@@ -33,11 +34,11 @@
             title = info.title?.toString() ?: "",
             subtitle = info.subtitle?.toString() ?: "",
             description = info.description?.toString() ?: "",
+            contentView = info.contentView,
             userInfo = userInfo,
             operationInfo = operationInfo,
             showEmergencyCallButton = info.isShowEmergencyCallButton
         ) {
-        val contentView: PromptContentView? = info.contentView
         val logoRes: Int = info.logoRes
         val logoBitmap: Bitmap? = info.logoBitmap
         val logoDescription: String? = info.logoDescription
@@ -54,6 +55,7 @@
             title = (info.deviceCredentialTitle ?: info.title)?.toString() ?: "",
             subtitle = (info.deviceCredentialSubtitle ?: info.subtitle)?.toString() ?: "",
             description = (info.deviceCredentialDescription ?: info.description)?.toString() ?: "",
+            contentView = info.contentView,
             userInfo = userInfo,
             operationInfo = operationInfo,
             showEmergencyCallButton = info.isShowEmergencyCallButton
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index cd5b124..ea39247 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -22,7 +22,6 @@
 import android.hardware.biometrics.BiometricAuthenticator
 import android.hardware.biometrics.BiometricConstants
 import android.hardware.biometrics.BiometricPrompt
-import android.hardware.biometrics.Flags.customBiometricPrompt
 import android.hardware.face.FaceManager
 import android.text.method.ScrollingMovementMethod
 import android.util.Log
@@ -151,17 +150,6 @@
             // these do not change and need to be set before any size transitions
             val modalities = viewModel.modalities.first()
 
-            // If there is no biometrics available, biometric prompt is showing just for displaying
-            // content, no authentication needed.
-            if (!(customBiometricPrompt() && modalities.isEmpty)) {
-                PromptIconViewBinder.bind(
-                    iconView,
-                    iconOverlayView,
-                    iconSizeOverride,
-                    viewModel,
-                )
-            }
-
             if (modalities.hasFingerprint) {
                 /**
                  * Load the given [rawResources] immediately so they are cached for use in the
@@ -233,6 +221,19 @@
                 )
             }
 
+            lifecycleScope.launch {
+                viewModel.showBpWithoutIconForCredential.collect {
+                    if (!it) {
+                        PromptIconViewBinder.bind(
+                            iconView,
+                            iconOverlayView,
+                            iconSizeOverride,
+                            viewModel,
+                        )
+                    }
+                }
+            }
+
             // TODO(b/251476085): migrate legacy icon controllers and remove
             // The fingerprint sensor is started by the legacy
             // AuthContainerView#onDialogAnimatedIn in all cases but the implicit coex flow
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index a37d916..8336d5e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -21,7 +21,6 @@
 import android.animation.ValueAnimator
 import android.graphics.Outline
 import android.graphics.Rect
-import android.hardware.biometrics.Flags
 import android.transition.AutoTransition
 import android.transition.TransitionManager
 import android.view.Surface
@@ -55,6 +54,7 @@
 import com.android.systemui.biometrics.ui.viewmodel.isRight
 import com.android.systemui.biometrics.ui.viewmodel.isSmall
 import com.android.systemui.biometrics.ui.viewmodel.isTop
+import com.android.systemui.keyguard.ui.view.layout.sections.setVisibility
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import kotlin.math.abs
@@ -111,14 +111,9 @@
 
             val smallConstraintSet = ConstraintSet()
             smallConstraintSet.clone(mediumConstraintSet)
-            viewsToHideWhenSmall.forEach { smallConstraintSet.setVisibility(it.id, View.GONE) }
 
             val largeConstraintSet = ConstraintSet()
             largeConstraintSet.clone(mediumConstraintSet)
-            viewsToHideWhenSmall.forEach { largeConstraintSet.setVisibility(it.id, View.GONE) }
-            largeConstraintSet.setVisibility(iconHolderView.id, View.GONE)
-            largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
-            largeConstraintSet.setVisibility(R.id.indicator, View.GONE)
             largeConstraintSet.setGuidelineBegin(leftGuideline.id, 0)
             largeConstraintSet.setGuidelineEnd(rightGuideline.id, 0)
             largeConstraintSet.setGuidelineEnd(bottomGuideline.id, 0)
@@ -219,13 +214,18 @@
                     }
                 }
 
-                view.repeatWhenAttached {
-                    var currentSize: PromptSize? = null
-                    val modalities = viewModel.modalities.first()
-                    // TODO(b/288175072): Move all visibility settings together.
-                    //  If there is no biometrics available, biometric prompt is showing just for
-                    // displaying content, no authentication needed.
-                    if (Flags.customBiometricPrompt() && modalities.isEmpty) {
+                fun setConstraintSetVisibility() {
+                    viewsToHideWhenSmall.forEach {
+                        mediumConstraintSet.setVisibility(it.id, it.showContentOrHide())
+                        largeConstraintSet.setVisibility(it.id, View.GONE)
+                        smallConstraintSet.setVisibility(it.id, View.GONE)
+                    }
+
+                    largeConstraintSet.setVisibility(iconHolderView.id, View.GONE)
+                    largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
+                    largeConstraintSet.setVisibility(R.id.indicator, View.GONE)
+
+                    if (viewModel.showBpWithoutIconForCredential.value) {
                         smallConstraintSet.setVisibility(iconHolderView.id, View.GONE)
                         smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
                         smallConstraintSet.setVisibility(R.id.indicator, View.GONE)
@@ -233,12 +233,17 @@
                         mediumConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE)
                         mediumConstraintSet.setVisibility(R.id.indicator, View.GONE)
                     }
+                }
+
+                view.repeatWhenAttached {
+                    var currentSize: PromptSize? = null
+
                     lifecycleScope.launch {
                         combine(viewModel.position, viewModel.size, ::Pair).collect {
                             (position, size) ->
                             view.doOnAttach {
                                 measureBounds(position)
-
+                                setConstraintSetVisibility()
                                 when {
                                     size.isSmall -> {
                                         val ratio =
@@ -313,7 +318,6 @@
                 // TODO(b/251476085): migrate the legacy panel controller and simplify this
                 view.repeatWhenAttached {
                     var currentSize: PromptSize? = null
-                    val modalities = viewModel.modalities.first()
                     lifecycleScope.launch {
                         /**
                          * View is only set visible in BiometricViewSizeBinder once PromptSize is
@@ -331,11 +335,13 @@
 
                             // prepare for animated size transitions
                             for (v in viewsToHideWhenSmall) {
-                                v.showContentOrHide(forceHide = size.isSmall)
+                                v.visibility = v.showContentOrHide(forceHide = size.isSmall)
                             }
-                            if (Flags.customBiometricPrompt() && modalities.isEmpty) {
+
+                            if (viewModel.showBpWithoutIconForCredential.value) {
                                 iconHolderView.visibility = View.GONE
                             }
+
                             if (currentSize == null && size.isSmall) {
                                 iconHolderView.alpha = 0f
                             }
@@ -344,9 +350,9 @@
                             }
 
                             // TODO(b/302735104): Fix wrong height due to the delay of
-                            // PromptContentView. addOnLayoutChangeListener() will cause crash when
-                            // showing credential view, since |PromptIconViewModel| won't release
-                            // the flow.
+                            // PromptContentView. addOnLayoutChangeListener() will cause crash
+                            // when showing credential view, since |PromptIconViewModel| won't
+                            // release the flow.
                             // propagate size changes to legacy panel controller and animate
                             // transitions
                             view.doOnLayout {
@@ -460,15 +466,14 @@
     return r == Surface.ROTATION_90 || r == Surface.ROTATION_270
 }
 
-private fun View.showContentOrHide(forceHide: Boolean = false) {
+private fun View.showContentOrHide(forceHide: Boolean = false): Int {
     val isTextViewWithBlankText = this is TextView && this.text.isBlank()
     val isImageViewWithoutImage = this is ImageView && this.drawable == null
-    visibility =
-        if (forceHide || isTextViewWithBlankText || isImageViewWithoutImage) {
-            View.GONE
-        } else {
-            View.VISIBLE
-        }
+    return if (forceHide || isTextViewWithBlankText || isImageViewWithoutImage) {
+        View.GONE
+    } else {
+        View.VISIBLE
+    }
 }
 
 private fun View.centerX(): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
index 03c5c53..46be8c7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
@@ -4,13 +4,13 @@
 import android.graphics.drawable.Drawable
 import android.text.InputType
 import com.android.internal.widget.LockPatternView
-import com.android.systemui.res.R
 import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.domain.interactor.CredentialStatus
 import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
 import com.android.systemui.biometrics.shared.model.BiometricUserInfo
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlin.reflect.KClass
 import kotlinx.coroutines.flow.Flow
@@ -32,14 +32,16 @@
 
     /** Top level information about the prompt. */
     val header: Flow<CredentialHeaderViewModel> =
-        credentialInteractor.prompt.filterIsInstance<BiometricPromptRequest.Credential>().map {
-            request ->
+        combine(
+            credentialInteractor.prompt.filterIsInstance<BiometricPromptRequest.Credential>(),
+            credentialInteractor.showBpWithoutIconForCredential
+        ) { request, showBpWithoutIconForCredential ->
             BiometricPromptHeaderViewModelImpl(
                 request,
                 user = request.userInfo,
                 title = request.title,
-                subtitle = request.subtitle,
-                description = request.description,
+                subtitle = if (showBpWithoutIconForCredential) "" else request.subtitle,
+                description = if (showBpWithoutIconForCredential) "" else request.description,
                 icon = applicationContext.asLockIcon(request.userInfo.deviceCredentialOwnerId),
                 showEmergencyCallButton = request.showEmergencyCallButton
             )
@@ -145,7 +147,7 @@
                 .createLaunchEmergencyDialerIntent(null)
                 .setFlags(
                     android.content.Intent.FLAG_ACTIVITY_NEW_TASK or
-                            android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
+                        android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
                 )
         context.startActivity(intent)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index c933e0e..2c749ba 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -47,6 +47,7 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asSharedFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
@@ -123,6 +124,9 @@
     /** The kind of credential the user has. */
     val credentialKind: Flow<PromptKind> = promptSelectorInteractor.credentialKind
 
+    val showBpWithoutIconForCredential: StateFlow<Boolean> =
+        promptSelectorInteractor.showBpWithoutIconForCredential
+
     /** The label to use for the cancel button. */
     val negativeButtonText: Flow<String> =
         promptSelectorInteractor.prompt.map { it?.negativeButtonText ?: "" }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
new file mode 100644
index 0000000..e789475
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.systemui.bouncer.shared.flag
+
+import com.android.systemui.Flags
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import dagger.Module
+import dagger.Provides
+
+interface ComposeBouncerFlags {
+
+    /**
+     * Returns `true` if the Compose bouncer is enabled or if the scene container framework is
+     * enabled; `false` otherwise.
+     */
+    fun isComposeBouncerOrSceneContainerEnabled(): Boolean
+
+    /**
+     * Returns `true` if only compose bouncer is enabled and scene container framework is not
+     * enabled.
+     */
+    @Deprecated(
+        "Avoid using this, this is meant to be used only by the glue code " +
+            "that includes compose bouncer in legacy keyguard.",
+        replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()")
+    )
+    fun isOnlyComposeBouncerEnabled(): Boolean
+}
+
+class ComposeBouncerFlagsImpl(private val sceneContainerFlags: SceneContainerFlags) :
+    ComposeBouncerFlags {
+
+    override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
+        return sceneContainerFlags.isEnabled() || Flags.composeBouncer()
+    }
+
+    @Deprecated(
+        "Avoid using this, this is meant to be used only by the glue code " +
+            "that includes compose bouncer in legacy keyguard.",
+        replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()")
+    )
+    override fun isOnlyComposeBouncerEnabled(): Boolean {
+        return !sceneContainerFlags.isEnabled() && Flags.composeBouncer()
+    }
+}
+
+@Module
+object ComposeBouncerFlagsModule {
+    @Provides
+    @SysUISingleton
+    fun impl(sceneContainerFlags: SceneContainerFlags): ComposeBouncerFlags {
+        return ComposeBouncerFlagsImpl(sceneContainerFlags)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index dd253a8..36d3ed52 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -4,10 +4,10 @@
 import com.android.keyguard.KeyguardMessageAreaController
 import com.android.keyguard.ViewMediatorCallback
 import com.android.keyguard.dagger.KeyguardBouncerComponent
-import com.android.systemui.Flags
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
 import com.android.systemui.bouncer.ui.BouncerDialogFactory
 import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
@@ -55,12 +55,15 @@
 class BouncerViewBinder
 @Inject
 constructor(
+    private val composeBouncerFlags: ComposeBouncerFlags,
     private val legacyBouncerDependencies: Lazy<LegacyBouncerDependencies>,
     private val composeBouncerDependencies: Lazy<ComposeBouncerDependencies>,
 ) {
     fun bind(view: ViewGroup) {
         if (
-            ComposeFacade.isComposeAvailable() && Flags.composeBouncer() && COMPOSE_BOUNCER_ENABLED
+            COMPOSE_BOUNCER_ENABLED &&
+                composeBouncerFlags.isOnlyComposeBouncerEnabled() &&
+                ComposeFacade.isComposeAvailable()
         ) {
             val deps = composeBouncerDependencies.get()
             ComposeBouncerViewBinder.bind(
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index 4466cbb..6287578 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
 import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
@@ -35,7 +36,6 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.inputmethod.domain.interactor.InputMethodInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.user.ui.viewmodel.UserActionViewModel
 import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel
@@ -72,7 +72,7 @@
     private val simBouncerInteractor: SimBouncerInteractor,
     private val authenticationInteractor: AuthenticationInteractor,
     private val selectedUserInteractor: SelectedUserInteractor,
-    flags: SceneContainerFlags,
+    flags: ComposeBouncerFlags,
     selectedUser: Flow<UserViewModel>,
     users: Flow<List<UserViewModel>>,
     userSwitcherMenu: Flow<List<UserActionViewModel>>,
@@ -233,7 +233,7 @@
     private var lockoutCountdownJob: Job? = null
 
     init {
-        if (flags.isEnabled()) {
+        if (flags.isComposeBouncerOrSceneContainerEnabled()) {
             // Keeps the lockout dialog up-to-date.
             applicationScope.launch {
                 bouncerInteractor.onLockoutStarted.collect {
@@ -478,7 +478,7 @@
         actionButtonInteractor: BouncerActionButtonInteractor,
         authenticationInteractor: AuthenticationInteractor,
         selectedUserInteractor: SelectedUserInteractor,
-        flags: SceneContainerFlags,
+        flags: ComposeBouncerFlags,
         userSwitcherViewModel: UserSwitcherViewModel,
         clock: SystemClock,
         devicePolicyManager: DevicePolicyManager,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index cf7d601..baae986 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -62,6 +62,10 @@
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.UserRepository
 import com.google.errorprone.annotations.CompileTimeConstant
+import java.io.PrintWriter
+import java.util.Arrays
+import java.util.stream.Collectors
+import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
@@ -83,10 +87,6 @@
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
-import java.io.PrintWriter
-import java.util.Arrays
-import java.util.stream.Collectors
-import javax.inject.Inject
 
 /**
  * API to run face authentication and detection for device entry / on keyguard (as opposed to the
@@ -431,11 +431,11 @@
             override fun onAuthenticationFailed() {
                 _isAuthenticated.value = false
                 faceAuthLogger.authenticationFailed()
+                _authenticationStatus.value = FailedFaceAuthenticationStatus()
                 if (!_isLockedOut.value) {
                     // onAuthenticationError gets invoked before onAuthenticationFailed when the
                     // last auth attempt locks out face authentication.
-                    // Skip updating the authentication status in such a scenario.
-                    _authenticationStatus.value = FailedFaceAuthenticationStatus()
+                    // Skip onFaceAuthRequestCompleted in such a scenario.
                     onFaceAuthRequestCompleted()
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt
index 6bfe8d9..846013c 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt
@@ -21,9 +21,12 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.FaceFailureMessage
+import com.android.systemui.deviceentry.shared.model.FaceLockoutMessage
 import com.android.systemui.deviceentry.shared.model.FaceMessage
 import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage
 import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus
+import com.android.systemui.deviceentry.shared.model.FingerprintFailureMessage
 import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage
 import com.android.systemui.deviceentry.shared.model.FingerprintMessage
 import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
@@ -97,11 +100,7 @@
         fingerprintAuthInteractor.fingerprintHelp
             .sample(biometricSettingsInteractor.fingerprintAuthCurrentlyAllowed, ::Pair)
             .filter { (_, fingerprintAuthAllowed) -> fingerprintAuthAllowed }
-            .map { (helpStatus, _) ->
-                FingerprintMessage(
-                    helpStatus.msg,
-                )
-            }
+            .map { (helpStatus, _) -> FingerprintMessage(helpStatus.msg) }
 
     private val fingerprintFailMessage: Flow<FingerprintMessage> =
         fingerprintPropertyInteractor.isUdfps.flatMapLatest { isUdfps ->
@@ -109,7 +108,7 @@
                 .sample(biometricSettingsInteractor.fingerprintAuthCurrentlyAllowed)
                 .filter { fingerprintAuthAllowed -> fingerprintAuthAllowed }
                 .map {
-                    FingerprintMessage(
+                    FingerprintFailureMessage(
                         if (isUdfps) {
                             resources.getString(
                                 com.android.internal.R.string.fingerprint_udfps_error_not_match
@@ -118,7 +117,7 @@
                             resources.getString(
                                 com.android.internal.R.string.fingerprint_error_not_match
                             )
-                        },
+                        }
                     )
                 }
         }
@@ -154,7 +153,7 @@
         faceFailure
             .sample(biometricSettingsInteractor.faceAuthCurrentlyAllowed)
             .filter { faceAuthCurrentlyAllowed -> faceAuthCurrentlyAllowed }
-            .map { FaceMessage(resources.getString(R.string.keyguard_face_failed)) }
+            .map { FaceFailureMessage(resources.getString(R.string.keyguard_face_failed)) }
 
     private val faceErrorMessage: Flow<FaceMessage> =
         faceError
@@ -173,6 +172,7 @@
                             FaceTimeoutMessage(status.msg)
                         }
                     }
+                    status.isLockoutError() -> FaceLockoutMessage(status.msg)
                     else -> FaceMessage(status.msg)
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt
index 59c3f7f..2ced8c41 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt
@@ -32,9 +32,15 @@
     private val faceTimeoutMessage: String?,
 ) : FaceMessage(faceTimeoutMessage)
 
+data class FaceLockoutMessage(private val msg: String?) : FaceMessage(msg)
+
+data class FaceFailureMessage(private val msg: String) : FaceMessage(msg)
+
 /** Fingerprint biometric message */
 open class FingerprintMessage(fingerprintMessage: String?) : BiometricMessage(fingerprintMessage)
 
 data class FingerprintLockoutMessage(
     private val fingerprintLockoutMessage: String?,
 ) : FingerprintMessage(fingerprintLockoutMessage)
+
+data class FingerprintFailureMessage(private val msg: String?) : FingerprintMessage(msg)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 7263ae9..cb1571e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -44,6 +44,7 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
@@ -287,7 +288,7 @@
         if (KeyguardWmStateRefactor.isEnabled) {
             // When the refactor is enabled, we no longer use isKeyguardGoingAway.
             scope.launch {
-                swipeToDismissInteractor.dismissFling.collect { _ ->
+                swipeToDismissInteractor.dismissFling.filterNotNull().collect { _ ->
                     startTransitionTo(KeyguardState.GONE)
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 719edd7..37b331c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.util.kotlin.pairwise
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -46,6 +47,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
 
 /** Encapsulates business-logic related to the keyguard transitions. */
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -206,6 +208,21 @@
             .shareIn(scope, SharingStarted.Eagerly, replay = 1)
 
     /**
+     * A pair of the most recent STARTED step, and the transition step immediately preceding it. The
+     * transition framework enforces that the previous step is either a CANCELED or FINISHED step,
+     * and that the previous step was *to* the state the STARTED step is *from*.
+     *
+     * This flow can be used to access the previous step to determine whether it was CANCELED or
+     * FINISHED. In the case of a CANCELED step, we can also figure out which state we were coming
+     * from when we were canceled.
+     */
+    val startedStepWithPrecedingStep =
+        transitions
+            .pairwise()
+            .filter { it.newValue.transitionState == TransitionState.STARTED }
+            .stateIn(scope, SharingStarted.Eagerly, null)
+
+    /**
      * The last [KeyguardState] to which we [TransitionState.FINISHED] a transition.
      *
      * WARNING: This will NOT emit a value if a transition is CANCELED, and will also not emit a
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index b81793e..cff74b3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -19,7 +19,9 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
@@ -121,19 +123,27 @@
      * want to know if the AOD/clock/notifs/etc. are visible.
      */
     val lockscreenVisibility: Flow<Boolean> =
-        combine(
-                transitionInteractor.startedKeyguardTransitionStep,
-                transitionInteractor.finishedKeyguardState,
-            ) { startedStep, finishedState ->
-                // If we finished the transition, use the finished state. If we're running a
-                // transition, use the state we're transitioning FROM. This can be different from
-                // the last finished state if a transition is interrupted. For example, if we were
-                // transitioning from GONE to AOD and then started AOD -> LOCKSCREEN mid-transition,
-                // we want to immediately use the visibility for AOD (lockscreenVisibility=true)
-                // even though the lastFinishedState is still GONE (lockscreenVisibility=false).
-                if (finishedState == startedStep.to) finishedState else startedStep.from
+        transitionInteractor.currentKeyguardState
+            .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair)
+            .map { (currentState, startedWithPrev) ->
+                val startedFromStep = startedWithPrev?.previousValue
+                val startedStep = startedWithPrev?.newValue
+                val returningToGoneAfterCancellation =
+                    startedStep?.to == KeyguardState.GONE &&
+                        startedFromStep?.transitionState == TransitionState.CANCELED &&
+                        startedFromStep.from == KeyguardState.GONE
+
+                if (!returningToGoneAfterCancellation) {
+                    // By default, apply the lockscreen visibility of the current state.
+                    KeyguardState.lockscreenVisibleInState(currentState)
+                } else {
+                    // If we're transitioning to GONE after a prior canceled transition from GONE,
+                    // then this is the camera launch transition from an asleep state back to GONE.
+                    // We don't want to show the lockscreen since we're aborting the lock and going
+                    // back to GONE.
+                    KeyguardState.lockscreenVisibleInState(KeyguardState.GONE)
+                }
             }
-            .map(KeyguardState::lockscreenVisibleInState)
             .distinctUntilChanged()
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt
new file mode 100644
index 0000000..2850b4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.systemui.media.controls.util
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the media_controls_refactor flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object MediaControlsRefactorFlag {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_MEDIA_CONTROLS_REFACTOR
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the flag enabled? */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.mediaControlsRefactor()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index 15747b9..d4bd6da 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -58,4 +58,7 @@
     /** Check whether to use scene framework */
     fun isSceneContainerEnabled() =
         sceneContainerFlags.isEnabled() && MediaInSceneContainerFlag.isEnabled
+
+    /** Check whether to use media refactor code */
+    fun isMediaControlsRefactorEnabled() = MediaControlsRefactorFlag.isEnabled
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
index 168fa08..15b8cfb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
@@ -39,6 +39,7 @@
         subtitleIdsMap["cast"] = R.array.tile_states_cast
         subtitleIdsMap["night"] = R.array.tile_states_night
         subtitleIdsMap["screenrecord"] = R.array.tile_states_screenrecord
+        subtitleIdsMap["record_issue"] = R.array.tile_states_record_issue
         subtitleIdsMap["reverse"] = R.array.tile_states_reverse
         subtitleIdsMap["reduce_brightness"] = R.array.tile_states_reduce_brightness
         subtitleIdsMap["cameratoggle"] = R.array.tile_states_cameratoggle
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
index b1e2467..20f3c4d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
@@ -85,7 +85,13 @@
 
     override fun getTileLabel(): CharSequence = mContext.getString(R.string.qs_record_issue_label)
 
-    override fun isAvailable(): Boolean = recordIssueQsTile()
+    /**
+     * There are SELinux constraints that are stopping this tile from reaching production builds.
+     * Once those are resolved, this condition will be removed, but the solution (of properly
+     * creating a distince SELinux context for com.android.systemui) is complex and will take time
+     * to implement.
+     */
+    override fun isAvailable(): Boolean = android.os.Build.IS_DEBUGGABLE && recordIssueQsTile()
 
     override fun newTileState(): QSTile.BooleanState =
         QSTile.BooleanState().apply {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index c7d3a4a..7d2468b 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.scene
 
 import com.android.systemui.CoreStartable
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlagsModule
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.startable.SceneContainerStartable
 import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule
@@ -34,6 +35,7 @@
         [
             BouncerSceneModule::class,
             CommunalSceneModule::class,
+            ComposeBouncerFlagsModule::class,
             EmptySceneModule::class,
             GoneSceneModule::class,
             LockscreenSceneModule::class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 19fe60a..1ec86ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -71,6 +71,7 @@
 import android.provider.DeviceConfig;
 import android.text.TextUtils;
 import android.text.format.Formatter;
+import android.util.Pair;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
@@ -187,6 +188,7 @@
     private CharSequence mTransientIndication;
     private CharSequence mBiometricMessage;
     private CharSequence mBiometricMessageFollowUp;
+    private BiometricSourceType mBiometricMessageSource;
     protected ColorStateList mInitialTextColorState;
     private boolean mVisible;
     private boolean mOrganizationOwnedDevice;
@@ -206,7 +208,7 @@
     private int mBatteryLevel;
     private boolean mBatteryPresent = true;
     private long mChargingTimeRemaining;
-    private String mBiometricErrorMessageToShowOnScreenOn;
+    private Pair<String, BiometricSourceType> mBiometricErrorMessageToShowOnScreenOn;
     private final Set<Integer> mCoExFaceAcquisitionMsgIdsToShow;
     private final FaceHelpMessageDeferral mFaceAcquiredMessageDeferral;
     private boolean mInited;
@@ -225,15 +227,18 @@
                 mIsActiveDreamLockscreenHosted = isLockscreenHosted;
                 updateDeviceEntryIndication(false);
             };
-    private final ScreenLifecycle.Observer mScreenObserver =
-            new ScreenLifecycle.Observer() {
+    private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
         @Override
         public void onScreenTurnedOn() {
             mHandler.removeMessages(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON);
             if (mBiometricErrorMessageToShowOnScreenOn != null) {
                 String followUpMessage = mFaceLockedOutThisAuthSession
                         ? faceLockedOutFollowupMessage() : null;
-                showBiometricMessage(mBiometricErrorMessageToShowOnScreenOn, followUpMessage);
+                showBiometricMessage(
+                        mBiometricErrorMessageToShowOnScreenOn.first,
+                        followUpMessage,
+                        mBiometricErrorMessageToShowOnScreenOn.second
+                );
                 // We want to keep this message around in case the screen was off
                 hideBiometricMessageDelayed(DEFAULT_HIDE_DELAY_MS);
                 mBiometricErrorMessageToShowOnScreenOn = null;
@@ -879,8 +884,35 @@
         updateTransient();
     }
 
-    private void showBiometricMessage(CharSequence biometricMessage) {
-        showBiometricMessage(biometricMessage, null);
+    private void showSuccessBiometricMessage(
+            CharSequence biometricMessage,
+            @Nullable CharSequence biometricMessageFollowUp,
+            BiometricSourceType biometricSourceType
+    ) {
+        showBiometricMessage(biometricMessage, biometricMessageFollowUp, biometricSourceType, true);
+    }
+
+    private void showSuccessBiometricMessage(CharSequence biometricMessage,
+            BiometricSourceType biometricSourceType) {
+        showSuccessBiometricMessage(biometricMessage, null, biometricSourceType);
+    }
+
+    private void showBiometricMessage(CharSequence biometricMessage,
+            BiometricSourceType biometricSourceType) {
+        showBiometricMessage(biometricMessage, null, biometricSourceType, false);
+    }
+
+    private void showBiometricMessage(
+            CharSequence biometricMessage,
+            @Nullable CharSequence biometricMessageFollowUp,
+            BiometricSourceType biometricSourceType
+    ) {
+        showBiometricMessage(
+                biometricMessage,
+                biometricMessageFollowUp,
+                biometricSourceType,
+                false
+        );
     }
 
     /**
@@ -889,15 +921,33 @@
      * by {@link KeyguardIndicationRotateTextViewController}, see class for rotating message
      * logic.
      */
-    private void showBiometricMessage(CharSequence biometricMessage,
-            @Nullable CharSequence biometricMessageFollowUp) {
+    private void showBiometricMessage(
+            CharSequence biometricMessage,
+            @Nullable CharSequence biometricMessageFollowUp,
+            BiometricSourceType biometricSourceType,
+            boolean isSuccessMessage
+    ) {
         if (TextUtils.equals(biometricMessage, mBiometricMessage)
+                && biometricSourceType == mBiometricMessageSource
                 && TextUtils.equals(biometricMessageFollowUp, mBiometricMessageFollowUp)) {
             return;
         }
 
+        if (!isSuccessMessage
+                && mBiometricMessageSource == FINGERPRINT
+                && biometricSourceType != FINGERPRINT) {
+            // drop all non-fingerprint biometric messages if there's a fingerprint message showing
+            mKeyguardLogger.logDropNonFingerprintMessage(
+                    biometricMessage,
+                    biometricMessageFollowUp,
+                    biometricSourceType
+            );
+            return;
+        }
+
         mBiometricMessage = biometricMessage;
         mBiometricMessageFollowUp = biometricMessageFollowUp;
+        mBiometricMessageSource = biometricSourceType;
 
         mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
         hideBiometricMessageDelayed(
@@ -914,6 +964,7 @@
         if (mBiometricMessage != null || mBiometricMessageFollowUp != null) {
             mBiometricMessage = null;
             mBiometricMessageFollowUp = null;
+            mBiometricMessageSource = null;
             mHideBiometricMessageHandler.cancel();
             updateBiometricMessage();
         }
@@ -1085,7 +1136,8 @@
                 } else {
                     message = mContext.getString(R.string.keyguard_retry);
                 }
-                mStatusBarKeyguardViewManager.setKeyguardMessage(message, mInitialTextColorState);
+                mStatusBarKeyguardViewManager.setKeyguardMessage(message, mInitialTextColorState,
+                        null);
             }
         } else {
             final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer(
@@ -1097,34 +1149,40 @@
                         || mAccessibilityManager.isTouchExplorationEnabled();
                 if (udfpsSupported && faceAuthenticated) { // co-ex
                     if (a11yEnabled) {
-                        showBiometricMessage(
+                        showSuccessBiometricMessage(
                                 mContext.getString(R.string.keyguard_face_successful_unlock),
-                                mContext.getString(R.string.keyguard_unlock)
+                                mContext.getString(R.string.keyguard_unlock),
+                                FACE
                         );
                     } else {
-                        showBiometricMessage(
+                        showSuccessBiometricMessage(
                                 mContext.getString(R.string.keyguard_face_successful_unlock),
-                                mContext.getString(R.string.keyguard_unlock_press)
+                                mContext.getString(R.string.keyguard_unlock_press),
+                                FACE
                         );
                     }
                 } else if (faceAuthenticated) { // face-only
-                    showBiometricMessage(
+                    showSuccessBiometricMessage(
                             mContext.getString(R.string.keyguard_face_successful_unlock),
-                            mContext.getString(R.string.keyguard_unlock)
+                            mContext.getString(R.string.keyguard_unlock),
+                            FACE
                     );
                 } else if (udfpsSupported) { // udfps-only
                     if (a11yEnabled) {
-                        showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+                        showSuccessBiometricMessage(
+                                mContext.getString(R.string.keyguard_unlock),
+                                null
+                        );
                     } else {
-                        showBiometricMessage(mContext.getString(
-                                R.string.keyguard_unlock_press));
+                        showSuccessBiometricMessage(mContext.getString(
+                                R.string.keyguard_unlock_press), null);
                     }
                 } else { // no security or unlocked by a trust agent
-                    showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+                    showSuccessBiometricMessage(mContext.getString(R.string.keyguard_unlock), null);
                 }
             } else {
                 // suggest swiping up for the primary authentication bouncer
-                showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+                showBiometricMessage(mContext.getString(R.string.keyguard_unlock), null);
             }
         }
     }
@@ -1228,6 +1286,13 @@
                     && msgId != BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
             final boolean faceAuthFailed = biometricSourceType == FACE
                     && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed
+            if (faceAuthFailed && mFaceLockedOutThisAuthSession) {
+                mKeyguardLogger.logBiometricMessage(
+                        "skipped showing faceAuthFailed message due to lockout",
+                        msgId,
+                        helpString);
+                return;
+            }
             final boolean fpAuthFailed = biometricSourceType == FINGERPRINT
                     && msgId == BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; // ran matcher & failed
             final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint();
@@ -1245,49 +1310,55 @@
                     mBouncerMessageInteractor.setFaceAcquisitionMessage(helpString);
                 }
                 mStatusBarKeyguardViewManager.setKeyguardMessage(helpString,
-                        mInitialTextColorState);
+                        mInitialTextColorState, biometricSourceType);
             } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
                 if (isCoExFaceAcquisitionMessage && msgId == FACE_ACQUIRED_TOO_DARK) {
                     showBiometricMessage(
                             helpString,
-                            mContext.getString(R.string.keyguard_suggest_fingerprint)
+                            mContext.getString(R.string.keyguard_suggest_fingerprint),
+                            biometricSourceType
                     );
                 } else if (faceAuthFailed && isUnlockWithFingerprintPossible) {
                     showBiometricMessage(
                             mContext.getString(R.string.keyguard_face_failed),
-                            mContext.getString(R.string.keyguard_suggest_fingerprint)
+                            mContext.getString(R.string.keyguard_suggest_fingerprint),
+                            biometricSourceType
                     );
                 } else if (fpAuthFailed
                         && mKeyguardUpdateMonitor.isCurrentUserUnlockedWithFace()) {
                     // face had already previously unlocked the device, so instead of showing a
                     // fingerprint error, tell them they have already unlocked with face auth
                     // and how to enter their device
-                    showBiometricMessage(
+                    showSuccessBiometricMessage(
                             mContext.getString(R.string.keyguard_face_successful_unlock),
-                            mContext.getString(R.string.keyguard_unlock)
+                            mContext.getString(R.string.keyguard_unlock),
+                            null
                     );
                 } else if (fpAuthFailed
                         && mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser())) {
-                    showBiometricMessage(
+                    showSuccessBiometricMessage(
                             getTrustGrantedIndication(),
-                            mContext.getString(R.string.keyguard_unlock)
+                            mContext.getString(R.string.keyguard_unlock),
+                            null
                     );
                 } else if (faceAuthUnavailable) {
                     showBiometricMessage(
                             helpString,
                             isUnlockWithFingerprintPossible
                                     ? mContext.getString(R.string.keyguard_suggest_fingerprint)
-                                    : mContext.getString(R.string.keyguard_unlock)
+                                    : mContext.getString(R.string.keyguard_unlock),
+                            biometricSourceType
                     );
                 } else {
-                    showBiometricMessage(helpString);
+                    showBiometricMessage(helpString, biometricSourceType);
                 }
             } else if (faceAuthFailed) {
                 // show action to unlock
                 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK),
                         TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
             } else {
-                mBiometricErrorMessageToShowOnScreenOn = helpString;
+                mBiometricErrorMessageToShowOnScreenOn =
+                        new Pair<>(helpString, biometricSourceType);
                 mHandler.sendMessageDelayed(
                         mHandler.obtainMessage(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON),
                         1000);
@@ -1333,7 +1404,7 @@
             } else if (mIndicationHelper.isFaceLockoutErrorMsg(msgId)) {
                 handleFaceLockoutError(errString);
             } else {
-                showErrorMessageNowOrLater(errString, null);
+                showErrorMessageNowOrLater(errString, null, FACE);
             }
         }
 
@@ -1343,7 +1414,7 @@
                         msgId,
                         errString);
             } else {
-                showErrorMessageNowOrLater(errString, null);
+                showErrorMessageNowOrLater(errString, null, FINGERPRINT);
             }
         }
 
@@ -1371,7 +1442,7 @@
 
         @Override
         public void onTrustAgentErrorMessage(CharSequence message) {
-            showBiometricMessage(message);
+            showBiometricMessage(message, null);
         }
 
         @Override
@@ -1459,12 +1530,13 @@
         // had too many unsuccessful attempts.
         if (!mFaceLockedOutThisAuthSession) {
             mFaceLockedOutThisAuthSession = true;
-            showErrorMessageNowOrLater(errString, followupMessage);
+            showErrorMessageNowOrLater(errString, followupMessage, FACE);
         } else if (!mAuthController.isUdfpsFingerDown()) {
             // On subsequent lockouts, we show a more generic locked out message.
             showErrorMessageNowOrLater(
                     mContext.getString(R.string.keyguard_face_unlock_unavailable),
-                    followupMessage);
+                    followupMessage,
+                    FACE);
         }
     }
 
@@ -1484,7 +1556,8 @@
                     && !mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 showBiometricMessage(
                         deferredFaceMessage,
-                        mContext.getString(R.string.keyguard_suggest_fingerprint)
+                        mContext.getString(R.string.keyguard_suggest_fingerprint),
+                        FACE
                 );
             } else {
                 // otherwise, don't show any message
@@ -1496,7 +1569,8 @@
             // user to manually retry.
             showBiometricMessage(
                     deferredFaceMessage,
-                    mContext.getString(R.string.keyguard_unlock)
+                    mContext.getString(R.string.keyguard_unlock),
+                    FACE
             );
         } else {
             // Face-only
@@ -1510,13 +1584,15 @@
                 getCurrentUser()) && mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed();
     }
 
-    private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg) {
+    private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg,
+            BiometricSourceType biometricSourceType) {
         if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
-            mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState);
+            mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState,
+                    biometricSourceType);
         } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
-            showBiometricMessage(errString, followUpMsg);
+            showBiometricMessage(errString, followUpMsg, biometricSourceType);
         } else {
-            mBiometricErrorMessageToShowOnScreenOn = errString;
+            mBiometricErrorMessageToShowOnScreenOn = new Pair<>(errString, biometricSourceType);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index 29627e1..f03c313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -119,6 +119,9 @@
             val needsRedaction = lockscreenUserManager.needsRedaction(entry)
             val isSensitive = userPublic && needsRedaction
             entry.setSensitive(isSensitive || shouldProtectNotification, deviceSensitive)
+            if (screenshareNotificationHiding()) {
+                entry.row?.setPublicExpanderVisible(!shouldProtectNotification)
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index decb244..322e93b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -218,6 +218,7 @@
     private boolean mShowingPublic;
     private boolean mSensitive;
     private boolean mSensitiveHiddenInGeneral;
+    private boolean mShowPublicExpander = true;
     private boolean mShowingPublicInitialized;
     private boolean mHideSensitiveForIntrinsicHeight;
     private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT;
@@ -599,8 +600,7 @@
             mNotificationParent.updateChildrenAppearance();
         }
         onAttachedChildrenCountChanged();
-        // The public layouts expand button is always visible
-        mPublicLayout.updateExpandButtons(true);
+        mPublicLayout.updateExpandButtons(mShowPublicExpander);
         updateLimits();
         updateShelfIconColor();
         if (mUpdateSelfBackgroundOnUpdate) {
@@ -2837,6 +2837,14 @@
         }
     }
 
+    /** Sets whether this notification row should show the notification expander or not */
+    public void setPublicExpanderVisible(boolean showPublicExpander) {
+        if (mShowPublicExpander != showPublicExpander) {
+            mShowPublicExpander = showPublicExpander;
+            mPublicLayout.updateExpandButtons(mShowPublicExpander);
+        }
+    }
+
     @Override
     public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
         mHideSensitiveForIntrinsicHeight = hideSensitive;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index e397a70..338d300 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -124,6 +124,7 @@
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.ColorUtilKt;
+import com.android.systemui.util.Compile;
 import com.android.systemui.util.DumpUtilsKt;
 
 import com.google.errorprone.annotations.CompileTimeConstant;
@@ -150,6 +151,7 @@
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
     private static final boolean SPEW = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG_UPDATE_SIDE_PADDING = Compile.IS_DEBUG;
 
     private boolean mShadeNeedsToClose = false;
 
@@ -218,6 +220,7 @@
     int mBottomInset = 0;
     private float mQsExpansionFraction;
     private final int mSplitShadeMinContentHeight;
+    private String mLastUpdateSidePaddingDumpString;
 
     /**
      * The algorithm which calculates the properties for our children
@@ -1106,15 +1109,28 @@
     }
 
     void updateSidePadding(int viewWidth) {
+        final boolean portrait =
+                getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
+
+        mLastUpdateSidePaddingDumpString = "viewWidth=" + viewWidth
+                + " skinnyNotifsInLandscape=" + mSkinnyNotifsInLandscape
+                + " portrait=" + portrait;
+
+        if (DEBUG_UPDATE_SIDE_PADDING) {
+            Log.v(TAG, "updateSidePadding: " + mLastUpdateSidePaddingDumpString);
+        }
+
         if (viewWidth == 0 || !mSkinnyNotifsInLandscape) {
             mSidePaddings = mMinimumPaddings;
             return;
         }
+
         // Portrait is easy, just use the dimen for paddings
-        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+        if (portrait) {
             mSidePaddings = mMinimumPaddings;
             return;
         }
+
         final int innerWidth = viewWidth - mMinimumPaddings * 2;
         final int qsTileWidth = (innerWidth - mQsTilePadding * 3) / 4;
         mSidePaddings = mMinimumPaddings + qsTileWidth + mQsTilePadding;
@@ -5294,6 +5310,11 @@
             println(pw, "translationX", getTranslationX());
             println(pw, "translationY", getTranslationY());
             println(pw, "translationZ", getTranslationZ());
+            println(pw, "skinnyNotifsInLandscape", mSkinnyNotifsInLandscape);
+            println(pw, "minimumPaddings", mMinimumPaddings);
+            println(pw, "qsTilePadding", mQsTilePadding);
+            println(pw, "sidePaddings", mSidePaddings);
+            println(pw, "lastUpdateSidePadding", mLastUpdateSidePaddingDumpString);
             mNotificationStackSizeCalculator.dump(pw, args);
         });
         pw.println();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index d10ca3d..6b47ac1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -239,10 +239,22 @@
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
         mStatusBarHeight = SystemBarUtils.getStatusBarHeight(mContext);
         layoutParams.height = mStatusBarHeight - waterfallTopInset;
+        updateSystemIconsContainerHeight();
         updatePaddings();
         setLayoutParams(layoutParams);
     }
 
+    private void updateSystemIconsContainerHeight() {
+        View systemIconsContainer = findViewById(R.id.system_icons);
+        ViewGroup.LayoutParams layoutParams = systemIconsContainer.getLayoutParams();
+        int newSystemIconsHeight =
+                getResources().getDimensionPixelSize(R.dimen.status_bar_system_icons_height);
+        if (layoutParams.height != newSystemIconsHeight) {
+            layoutParams.height = newSystemIconsHeight;
+            systemIconsContainer.setLayoutParams(layoutParams);
+        }
+    }
+
     private void updatePaddings() {
         int statusBarPaddingStart = getResources().getDimensionPixelSize(
                 R.dimen.status_bar_padding_start);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index a39bfe0..68a0e9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -18,6 +18,7 @@
 import android.app.StatusBarManager.WINDOW_STATUS_BAR
 import android.graphics.Point
 import android.util.Log
+import android.view.InputDevice
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
@@ -81,7 +82,22 @@
         statusContainer.setOnHoverListener(
             statusOverlayHoverListenerFactory.createDarkAwareListener(statusContainer)
         )
-        statusContainer.setOnClickListener { shadeViewController.expand(/* animate= */true) }
+        statusContainer.setOnTouchListener(object : View.OnTouchListener {
+            override fun onTouch(v: View, event: MotionEvent): Boolean {
+                // We want to handle only mouse events here to avoid stealing finger touches from
+                // status bar which expands shade when swiped down on. We're using onTouchListener
+                // instead of onClickListener as the later will lead to isClickable being set to
+                // true and hence ALL touches always being intercepted. See [View.OnTouchEvent]
+                if (event.source == InputDevice.SOURCE_MOUSE) {
+                    if (event.action == MotionEvent.ACTION_UP) {
+                        v.performClick()
+                        shadeViewController.expand(/* animate= */ true)
+                    }
+                    return true
+                }
+                return false
+            }
+        })
 
         progressProvider?.setReadyToHandleTransition(true)
         configurationController.addCallback(configurationListener)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 29fd225..d1055c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -23,7 +23,6 @@
 import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
-import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 import static com.android.systemui.util.kotlin.JavaAdapterKt.combineFlows;
 
 import android.content.Context;
@@ -98,6 +97,7 @@
 import com.android.systemui.unfold.FoldAodAnimationController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
+import com.android.systemui.util.kotlin.JavaAdapter;
 
 import dagger.Lazy;
 
@@ -348,6 +348,8 @@
     private Lazy<KeyguardSurfaceBehindInteractor> mSurfaceBehindInteractor;
     private Lazy<KeyguardDismissActionInteractor> mKeyguardDismissActionInteractor;
 
+    private final JavaAdapter mJavaAdapter;
+
     @Inject
     public StatusBarKeyguardViewManager(
             Context context,
@@ -378,7 +380,8 @@
             Lazy<WindowManagerLockscreenVisibilityInteractor> wmLockscreenVisibilityInteractor,
             Lazy<KeyguardDismissActionInteractor> keyguardDismissActionInteractorLazy,
             SelectedUserInteractor selectedUserInteractor,
-            Lazy<KeyguardSurfaceBehindInteractor> surfaceBehindInteractor
+            Lazy<KeyguardSurfaceBehindInteractor> surfaceBehindInteractor,
+            JavaAdapter javaAdapter
     ) {
         mContext = context;
         mViewMediatorCallback = callback;
@@ -411,6 +414,7 @@
         mKeyguardDismissActionInteractor = keyguardDismissActionInteractorLazy;
         mSelectedUserInteractor = selectedUserInteractor;
         mSurfaceBehindInteractor = surfaceBehindInteractor;
+        mJavaAdapter = javaAdapter;
     }
 
     KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -481,8 +485,7 @@
 
         if (KeyguardWmStateRefactor.isEnabled()) {
             // Show the keyguard views whenever we've told WM that the lockscreen is visible.
-            collectFlow(
-                    getViewRootImpl().getView(),
+            mJavaAdapter.alwaysCollectFlow(
                     combineFlows(
                             mWmLockscreenVisibilityInteractor.get().getLockscreenVisibility(),
                             mSurfaceBehindInteractor.get().isAnimatingSurface(),
@@ -781,7 +784,7 @@
                     }
 
                     updateAlternateBouncerShowing(mAlternateBouncerInteractor.show());
-                    setKeyguardMessage(message, null);
+                    setKeyguardMessage(message, null, null);
                     return;
                 }
 
@@ -1444,11 +1447,12 @@
     }
 
     /** Display security message to relevant KeyguardMessageArea. */
-    public void setKeyguardMessage(String message, ColorStateList colorState) {
+    public void setKeyguardMessage(String message, ColorStateList colorState,
+            BiometricSourceType biometricSourceType) {
         if (mAlternateBouncerInteractor.isVisibleState()) {
             if (mKeyguardMessageAreaController != null) {
                 DeviceEntryUdfpsRefactor.assertInLegacyMode();
-                mKeyguardMessageAreaController.setMessage(message);
+                mKeyguardMessageAreaController.setMessage(message, biometricSourceType);
             }
         } else {
             mPrimaryBouncerInteractor.showMessage(message, colorState);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
index d4522d0..93e7602 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
@@ -19,11 +19,14 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.hardware.biometrics.BiometricSourceType;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -119,4 +122,51 @@
         when(mKeyguardMessageArea.getText()).thenReturn(msg);
         assertThat(mMessageAreaController.getMessage()).isEqualTo(msg);
     }
+
+    @Test
+    public void testFingerprintMessageUpdate() {
+        String msg = "fpMessage";
+        mMessageAreaController.setMessage(
+                msg, BiometricSourceType.FINGERPRINT
+        );
+        verify(mKeyguardMessageArea).setMessage(msg, /* animate= */ true);
+
+        String msg2 = "fpMessage2";
+        mMessageAreaController.setMessage(
+                msg2, BiometricSourceType.FINGERPRINT
+        );
+        verify(mKeyguardMessageArea).setMessage(msg2, /* animate= */ true);
+    }
+
+    @Test
+    public void testFaceMessageDroppedWhileFingerprintMessageShowing() {
+        String fpMsg = "fpMessage";
+        mMessageAreaController.setMessage(
+                fpMsg, BiometricSourceType.FINGERPRINT
+        );
+        verify(mKeyguardMessageArea).setMessage(eq(fpMsg), /* animate= */ anyBoolean());
+
+        String faceMessage = "faceMessage";
+        mMessageAreaController.setMessage(
+                faceMessage, BiometricSourceType.FACE
+        );
+        verify(mKeyguardMessageArea, never())
+                .setMessage(eq(faceMessage), /* animate= */ anyBoolean());
+    }
+
+    @Test
+    public void testGenericMessageShowsAfterFingerprintMessageShowing() {
+        String fpMsg = "fpMessage";
+        mMessageAreaController.setMessage(
+                fpMsg, BiometricSourceType.FINGERPRINT
+        );
+        verify(mKeyguardMessageArea).setMessage(eq(fpMsg), /* animate= */ anyBoolean());
+
+        String genericMessage = "genericMessage";
+        mMessageAreaController.setMessage(
+                genericMessage, null
+        );
+        verify(mKeyguardMessageArea)
+                .setMessage(eq(genericMessage), /* animate= */ anyBoolean());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index 2c1a87d..10b86ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -21,8 +21,8 @@
 import android.hardware.biometrics.BiometricConstants
 import android.hardware.biometrics.BiometricManager
 import android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT
-import android.hardware.biometrics.Flags.customBiometricPrompt
 import android.hardware.biometrics.PromptInfo
+import android.hardware.biometrics.PromptVerticalListContentView
 import android.hardware.face.FaceSensorPropertiesInternal
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.os.Handler
@@ -40,7 +40,6 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.Flags.FLAG_CONSTRAINT_BP
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
 import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
@@ -148,8 +147,6 @@
 
     @Before
     fun setup() {
-        mSetFlagsRule.disableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
-        mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP)
         displayRepository = FakeDisplayRepository()
 
         displayStateInteractor =
@@ -388,9 +385,10 @@
     }
 
     @Test
-    fun testShowCredentialUI() {
+    fun testShowCredentialUI_withDescription() {
+        mSetFlagsRule.disableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
         val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
         )
         waitForIdleSync()
 
@@ -399,16 +397,12 @@
     }
 
     @Test
-    fun testShowBiometricUIWhenCustomBpEnabledAndNoSensors() {
-        mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
+    fun testShowCredentialUI_withCustomBp() {
         val container = initializeFingerprintContainer(
-                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+                isUsingContentView = true
         )
-        waitForIdleSync()
-
-        assertThat(customBiometricPrompt()).isTrue()
-        assertThat(container.hasBiometricPrompt()).isTrue()
-        assertThat(container.hasCredentialView()).isFalse()
+        checkBpShowsForCredentialAndGoToCredential(container)
     }
 
     @Test
@@ -512,11 +506,13 @@
 
     private fun initializeFingerprintContainer(
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
-        addToView: Boolean = true
+        addToView: Boolean = true,
+        isUsingContentView: Boolean = false,
     ) = initializeContainer(
         TestAuthContainerView(
             authenticators = authenticators,
-            fingerprintProps = fingerprintSensorPropertiesInternal()
+            fingerprintProps = fingerprintSensorPropertiesInternal(),
+                isUsingContentView = isUsingContentView,
         ),
         addToView
     )
@@ -549,7 +545,8 @@
     private inner class TestAuthContainerView(
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
         fingerprintProps: List<FingerprintSensorPropertiesInternal> = listOf(),
-        faceProps: List<FaceSensorPropertiesInternal> = listOf()
+        faceProps: List<FaceSensorPropertiesInternal> = listOf(),
+        isUsingContentView: Boolean = false,
     ) : AuthContainerView(
         Config().apply {
             mContext = this@AuthContainerViewTest.context
@@ -559,6 +556,9 @@
             mSkipAnimation = true
             mPromptInfo = PromptInfo().apply {
                 this.authenticators = authenticators
+                if (isUsingContentView) {
+                    this.contentView = PromptVerticalListContentView.Builder().build()
+                }
             }
             mOpPackageName = OP_PACKAGE_NAME
         },
@@ -614,6 +614,17 @@
         val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
         assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.systemBars()) == 0).isTrue()
     }
+
+    private fun checkBpShowsForCredentialAndGoToCredential(container: TestAuthContainerView) {
+        waitForIdleSync()
+        assertThat(container.hasBiometricPrompt()).isTrue()
+        assertThat(container.hasCredentialView()).isFalse()
+
+        container.animateToCredentialUI(false)
+        waitForIdleSync()
+        assertThat(container.hasBiometricPrompt()).isFalse()
+        assertThat(container.hasCredentialView()).isTrue()
+    }
 }
 
 private fun AuthContainerView.hasBiometricPrompt() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
index b39e09d..7b972d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.biometrics.data.repository
 
+import android.hardware.biometrics.BiometricManager
 import android.hardware.biometrics.PromptInfo
+import android.hardware.biometrics.PromptVerticalListContentView
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
@@ -131,6 +133,52 @@
         }
 
     @Test
+    fun showBpWithoutIconForCredential_withCustomBp() =
+        testScope.runTest {
+            for (case in
+                listOf(
+                    PromptKind.Biometric(),
+                    PromptKind.Pin,
+                    PromptKind.Password,
+                    PromptKind.Pattern
+                )) {
+                val hasCredentialViewShown = case !is PromptKind.Biometric
+                val promptInfo =
+                    PromptInfo().apply {
+                        authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+                        contentView = PromptVerticalListContentView.Builder().build()
+                    }
+                repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME)
+                repository.setShouldShowBpWithoutIconForCredential(promptInfo)
+
+                assertThat(repository.showBpWithoutIconForCredential.value)
+                    .isEqualTo(!hasCredentialViewShown)
+            }
+        }
+
+    @Test
+    fun showBpWithoutIconForCredential_withDescription() =
+        testScope.runTest {
+            for (case in
+                listOf(
+                    PromptKind.Biometric(),
+                    PromptKind.Pin,
+                    PromptKind.Password,
+                    PromptKind.Pattern
+                )) {
+                val promptInfo =
+                    PromptInfo().apply {
+                        authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+                        description = "description"
+                    }
+                repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME)
+                repository.setShouldShowBpWithoutIconForCredential(promptInfo)
+
+                assertThat(repository.showBpWithoutIconForCredential.value).isFalse()
+            }
+        }
+
+    @Test
     fun setsAndUnsetsPrompt() =
         testScope.runTest {
             val kind = PromptKind.Pin
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
index 52b4275..2817780 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -147,7 +147,7 @@
         testScope.runTest { useCredentialAndReset(Utils.CREDENTIAL_PIN) }
 
     @Test
-    fun usePattermCredentialAndReset() =
+    fun usePatternCredentialAndReset() =
         testScope.runTest { useCredentialAndReset(Utils.CREDENTIAL_PATTERN) }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
index 6d8e7aa..6aebe36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
@@ -126,7 +126,7 @@
             keyguardRepository.setKeyguardDismissible(true)
             runCurrent()
             shadeRepository.setCurrentFling(
-                FlingInfo(expand = true) // Not a dismiss fling (expand = true).
+                FlingInfo(expand = false) // Is a dismiss fling upward (expand = false).
             )
             runCurrent()
 
@@ -153,4 +153,22 @@
 
             assertThatRepository(transitionRepository).noTransitionsStarted()
         }
+
+    @Test
+    @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+    fun testDoesNotTransitionToGone_whenDismissFling_emitsNull() =
+        testScope.runTest {
+            underTest.start()
+            verify(transitionRepository, never()).startTransition(any())
+
+            keyguardRepository.setKeyguardDismissible(true)
+            runCurrent()
+
+            // The fling is null when it a) initializes b) ends and in either case we should not
+            // swipe to unlock.
+            shadeRepository.setCurrentFling(null)
+            runCurrent()
+
+            assertThatRepository(transitionRepository).noTransitionsStarted()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index a4483bd..6d605a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -375,4 +375,323 @@
                 values
             )
         }
+
+    @Test
+    fun testLockscreenVisibility_usesFromState_ifCanceled() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenVisibility)
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope
+            )
+
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    // Initially should be true, as we start in LOCKSCREEN.
+                    true,
+                    // Then, false, since we finish in GONE.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.RUNNING,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    // Should remain false as we transition from GONE.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.CANCELED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.LOCKSCREEN,
+                )
+            )
+
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    // If we cancel and then go from LS -> GONE, we should immediately flip to the
+                    // visibility of the from state (LS).
+                    true,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.FINISHED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.LOCKSCREEN,
+                )
+            )
+
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    true,
+                ),
+                values
+            )
+        }
+
+    /**
+     * Tests the special case for insecure camera launch. CANCELING a transition from GONE and then
+     * STARTING a transition back to GONE should never show the lockscreen, even though the current
+     * state during the AOD/isAsleep -> GONE transition is AOD (where lockscreen visibility = true).
+     */
+    @Test
+    fun testLockscreenVisibility_falseDuringTransitionToGone_fromCanceledGone() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenVisibility)
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope
+            )
+
+            runCurrent()
+            assertEquals(
+                listOf(
+                    true,
+                    // Not visible since we're GONE.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.RUNNING,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.CANCELED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+            runCurrent()
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.RUNNING,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+            runCurrent()
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.FINISHED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+
+            runCurrent()
+            assertEquals(
+                listOf(
+                    true,
+                    // Remains not visible from GONE -> AOD (canceled) -> AOD since we never
+                    // FINISHED in AOD, and special-case handling for the insecure camera launch
+                    // ensures that we use the lockscreen visibility for GONE (false) if we're
+                    // STARTED to GONE after a CANCELED from GONE.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                testScope,
+            )
+
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    // Make sure there's no stuck overrides or something - we should make lockscreen
+                    // visible again once we're finished in LOCKSCREEN.
+                    true,
+                ),
+                values
+            )
+        }
+
+    /**  */
+    @Test
+    fun testLockscreenVisibility_trueDuringTransitionToGone_fromNotCanceledGone() =
+        testScope.runTest {
+            val values by collectValues(underTest.lockscreenVisibility)
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope
+            )
+
+            runCurrent()
+            assertEquals(
+                listOf(
+                    true,
+                    // Not visible when finished in GONE.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.RUNNING,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    // Still not visible during GONE -> AOD.
+                    false,
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.FINISHED,
+                    from = KeyguardState.GONE,
+                    to = KeyguardState.AOD,
+                )
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    // Visible now that we're FINISHED in AOD.
+                    true
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.STARTED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+            runCurrent()
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.RUNNING,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    // Remains visible from AOD during transition.
+                    true
+                ),
+                values
+            )
+
+            transitionRepository.sendTransitionStep(
+                TransitionStep(
+                    transitionState = TransitionState.FINISHED,
+                    from = KeyguardState.AOD,
+                    to = KeyguardState.GONE,
+                )
+            )
+
+            runCurrent()
+            assertEquals(
+                listOf(
+                    true,
+                    false,
+                    true,
+                    // Until we're finished in GONE again.
+                    false
+                ),
+                values
+            )
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index aa53558..1504d4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -92,6 +92,21 @@
 @TestableLooper.RunWithLooper
 public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest {
     @Test
+    public void afterFaceLockout_skipShowingFaceNotRecognized() {
+        createController();
+        onFaceLockoutError("lockout");
+        verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "lockout");
+        clearInvocations(mRotateTextViewController);
+
+        // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED (face fail)
+        mKeyguardUpdateMonitorCallback.onBiometricHelp(
+                BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
+                "Face not recognized",
+                BiometricSourceType.FACE);
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); // no updated message
+    }
+
+    @Test
     public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() {
         // GIVEN a controller with a mocked rotate text view controlller
         final KeyguardIndicationRotateTextViewController mockedRotateTextViewController =
@@ -593,7 +608,7 @@
         mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT,
                 "A message", BiometricSourceType.FACE);
 
-        verify(mStatusBarKeyguardViewManager).setKeyguardMessage(eq(message), any());
+        verify(mStatusBarKeyguardViewManager).setKeyguardMessage(eq(message), any(), any());
     }
 
     @Test
@@ -608,7 +623,8 @@
         mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT,
                 "A message", BiometricSourceType.FACE);
 
-        verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage(eq(message), any());
+        verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage(
+                eq(message), any(), any());
     }
 
     @Test
@@ -1242,7 +1258,7 @@
     public void onBiometricFailed_resetFaceHelpMessageDeferral() {
         createController();
 
-        // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED
+        // WHEN face sends an onBiometricAuthFailed
         mKeyguardUpdateMonitorCallback.onBiometricAuthFailed(BiometricSourceType.FACE);
 
         // THEN face help message deferral is reset
@@ -1331,7 +1347,9 @@
         verify(mStatusBarKeyguardViewManager)
                 .setKeyguardMessage(
                         eq(mContext.getString(R.string.keyguard_face_unlock_unavailable)),
-                        any());
+                        any(),
+                        any()
+                );
     }
 
     @Test
@@ -1471,6 +1489,71 @@
                 mContext.getString(R.string.keyguard_suggest_fingerprint));
     }
 
+    @Test
+    public void faceErrorMessageDroppedBecauseFingerprintMessageShowing() {
+        createController();
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                "fp not recognized", BiometricSourceType.FINGERPRINT);
+        clearInvocations(mRotateTextViewController);
+
+        onFaceLockoutError("lockout");
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+    }
+
+    @Test
+    public void faceUnlockedMessageShowsEvenWhenFingerprintMessageShowing() {
+        createController();
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                "fp not recognized", BiometricSourceType.FINGERPRINT);
+        clearInvocations(mRotateTextViewController);
+
+        when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
+                .thenReturn(true);
+        mController.getKeyguardCallback().onBiometricAuthenticated(0,
+                BiometricSourceType.FACE, false);
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                mContext.getString(R.string.keyguard_face_successful_unlock));
+    }
+
+    @Test
+    public void onTrustAgentErrorMessageDroppedBecauseFingerprintMessageShowing() {
+        createController();
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                "fp not recognized", BiometricSourceType.FINGERPRINT);
+        clearInvocations(mRotateTextViewController);
+
+        mKeyguardUpdateMonitorCallback.onTrustAgentErrorMessage("testMessage");
+        verifyNoMessage(INDICATION_TYPE_TRUST);
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+    }
+
+    @Test
+    public void trustGrantedMessageShowsEvenWhenFingerprintMessageShowing() {
+        createController();
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                "fp not recognized", BiometricSourceType.FINGERPRINT);
+        clearInvocations(mRotateTextViewController);
+
+        // GIVEN trust is granted
+        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
+
+        // WHEN the showTrustGranted method is called
+        final String trustGrantedMsg = "testing trust granted message after fp message";
+        mController.getKeyguardCallback().onTrustGrantedForCurrentUser(
+                false, false, new TrustGrantFlags(0), trustGrantedMsg);
+
+        // THEN verify the trust granted message shows
+        verifyIndicationMessage(
+                INDICATION_TYPE_TRUST,
+                trustGrantedMsg);
+    }
+
     private void screenIsTurningOn() {
         when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_TURNING_ON);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index 7d99d05..457d2f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -130,6 +131,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(false, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -156,6 +158,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, false)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -196,6 +199,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(false, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -222,6 +226,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, false)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -262,6 +267,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(false, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -288,6 +294,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, false)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -329,6 +336,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(false, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -356,6 +364,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -396,6 +405,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -422,6 +432,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -462,6 +473,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(false, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -489,6 +501,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -531,6 +544,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
     }
 
     @Test
@@ -559,6 +573,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!).setSensitive(true, true)
+        verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
     }
 
     @Test
@@ -584,6 +599,7 @@
         onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
 
         verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
+        verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any())
     }
 
     private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry {
@@ -591,7 +607,11 @@
             mock<UserHandle>().apply { whenever(identifier).thenReturn(notifUserId) }
         val mockSbn: StatusBarNotification =
             mock<StatusBarNotification>().apply { whenever(user).thenReturn(mockUserHandle) }
-        val mockEntry = mock<NotificationEntry>().apply { whenever(sbn).thenReturn(mockSbn) }
+        val mockRow: ExpandableNotificationRow = mock<ExpandableNotificationRow>()
+        val mockEntry = mock<NotificationEntry>().apply {
+            whenever(sbn).thenReturn(mockSbn)
+            whenever(row).thenReturn(mockRow)
+        }
         whenever(lockscreenUserManager.needsRedaction(mockEntry)).thenReturn(needsRedaction)
         whenever(mockEntry.rowExists()).thenReturn(true)
         return object : ListEntry("key", 0) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 1687ccb..3792d5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -20,6 +20,7 @@
 import android.app.StatusBarManager.WINDOW_STATE_HIDING
 import android.app.StatusBarManager.WINDOW_STATE_SHOWING
 import android.app.StatusBarManager.WINDOW_STATUS_BAR
+import android.view.InputDevice
 import android.view.LayoutInflater
 import android.view.MotionEvent
 import android.view.View
@@ -239,11 +240,42 @@
             controller = createAndInitController(view)
         }
         val statusContainer = view.requireViewById<View>(R.id.system_icons)
-        statusContainer.performClick()
+        statusContainer.dispatchTouchEvent(
+            getMotionEventFromSource(
+                MotionEvent.ACTION_UP,
+                0,
+                0,
+                InputDevice.SOURCE_MOUSE
+            )
+        )
         verify(shadeViewController).expand(any())
     }
 
     @Test
+    fun statusIconContainerIsNotHandlingTouchScreenTouches() {
+        val view = createViewMock()
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            controller = createAndInitController(view)
+        }
+        val statusContainer = view.requireViewById<View>(R.id.system_icons)
+        val handled = statusContainer.dispatchTouchEvent(
+            getMotionEventFromSource(
+                MotionEvent.ACTION_UP,
+                0,
+                0,
+                InputDevice.SOURCE_TOUCHSCREEN
+            )
+        )
+        assertThat(handled).isFalse()
+    }
+
+    private fun getMotionEventFromSource(action: Int, x: Int, y: Int, source: Int): MotionEvent {
+        val ev = MotionEvent.obtain(0, 0, action, x.toFloat(), y.toFloat(), 0)
+        ev.source = source
+        return ev
+    }
+
+    @Test
     fun shadeIsNotExpandedOnStatusBarGeneralClick() {
         val view = createViewMock()
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
index 5e8b62e..fd2dead 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
@@ -26,6 +26,7 @@
 import android.view.MotionEvent
 import android.view.PrivacyIndicatorBounds
 import android.view.RoundedCorners
+import android.view.View
 import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
@@ -50,6 +51,8 @@
 class PhoneStatusBarViewTest : SysuiTestCase() {
 
     private lateinit var view: PhoneStatusBarView
+    private val systemIconsContainer: View
+        get() = view.requireViewById(R.id.system_icons)
 
     private val contentInsetsProvider = mock<StatusBarContentInsetsProvider>()
     private val windowController = mock<StatusBarWindowController>()
@@ -62,6 +65,7 @@
         )
         mDependency.injectTestDependency(DarkIconDispatcher::class.java, mock<DarkIconDispatcher>())
         mDependency.injectTestDependency(StatusBarWindowController::class.java, windowController)
+        context.ensureTestableResources()
         view = spy(createStatusBarView())
         whenever(view.rootWindowInsets).thenReturn(emptyWindowInsets())
         whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
@@ -217,7 +221,7 @@
 
         val newInsets = Insets.NONE
         whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
-                .thenReturn(newInsets)
+            .thenReturn(newInsets)
         view.onConfigurationChanged(Configuration())
 
         assertThat(view.paddingLeft).isEqualTo(previousInsets.left)
@@ -239,7 +243,7 @@
 
         val newInsets = Insets.NONE
         whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
-                .thenReturn(newInsets)
+            .thenReturn(newInsets)
         configuration.densityDpi = 456
         view.onConfigurationChanged(configuration)
 
@@ -262,7 +266,7 @@
 
         val newInsets = Insets.NONE
         whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
-                .thenReturn(newInsets)
+            .thenReturn(newInsets)
         configuration.fontScale = 2f
         view.onConfigurationChanged(configuration)
 
@@ -273,6 +277,19 @@
     }
 
     @Test
+    fun onConfigurationChanged_systemIconsHeightChanged_containerHeightIsUpdated() {
+        val newHeight = 123456
+        context.orCreateTestableResources.addOverride(
+            R.dimen.status_bar_system_icons_height,
+            newHeight
+        )
+
+        view.onConfigurationChanged(Configuration())
+
+        assertThat(systemIconsContainer.layoutParams.height).isEqualTo(newHeight)
+    }
+
+    @Test
     fun onApplyWindowInsets_updatesLeftTopRightPaddingsBasedOnInsets() {
         val insets = Insets.of(/* left = */ 90, /* top = */ 10, /* right = */ 45, /* bottom = */ 50)
         whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index bd7406a..3666248 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -97,6 +97,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
+import com.android.systemui.util.kotlin.JavaAdapter;
 
 import com.google.common.truth.Truth;
 
@@ -222,7 +223,8 @@
                         () -> mock(WindowManagerLockscreenVisibilityInteractor.class),
                         () -> mock(KeyguardDismissActionInteractor.class),
                         mSelectedUserInteractor,
-                        () -> mock(KeyguardSurfaceBehindInteractor.class)) {
+                        () -> mock(KeyguardSurfaceBehindInteractor.class),
+                        mock(JavaAdapter.class)) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -730,7 +732,8 @@
                         () -> mock(WindowManagerLockscreenVisibilityInteractor.class),
                         () -> mock(KeyguardDismissActionInteractor.class),
                         mSelectedUserInteractor,
-                        () -> mock(KeyguardSurfaceBehindInteractor.class)) {
+                        () -> mock(KeyguardSurfaceBehindInteractor.class),
+                        mock(JavaAdapter.class)) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
index f192de2..c3af437 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
@@ -1,6 +1,8 @@
 package com.android.systemui.biometrics.data.repository
 
+import android.hardware.biometrics.Flags
 import android.hardware.biometrics.PromptInfo
+import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.shared.model.PromptKind
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -26,6 +28,9 @@
     private val _isConfirmationRequired = MutableStateFlow(false)
     override val isConfirmationRequired = _isConfirmationRequired.asStateFlow()
 
+    private val _showBpWithoutIconForCredential = MutableStateFlow(false)
+    override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow()
+
     private val _opPackageName: MutableStateFlow<String?> = MutableStateFlow(null)
     override val opPackageName = _opPackageName.asStateFlow()
 
@@ -69,6 +74,16 @@
         _isConfirmationRequired.value = false
     }
 
+    override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) {
+        val hasCredentialViewShown = kind.value !is PromptKind.Biometric
+        val showBpForCredential =
+            Flags.customBiometricPrompt() &&
+                !Utils.isBiometricAllowed(promptInfo) &&
+                Utils.isDeviceCredentialAllowed(promptInfo) &&
+                promptInfo.contentView != null
+        _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown
+    }
+
     fun setIsShowing(showing: Boolean) {
         _isShowing.value = showing
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
new file mode 100644
index 0000000..5c3e1f4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.systemui.bouncer.shared.flag
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
+
+var Kosmos.fakeComposeBouncerFlags by
+    Kosmos.Fixture { FakeComposeBouncerFlags(fakeSceneContainerFlags) }
+val Kosmos.composeBouncerFlags by Kosmos.Fixture<ComposeBouncerFlags> { fakeComposeBouncerFlags }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
new file mode 100644
index 0000000..c116bbd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.systemui.bouncer.shared.flag
+
+import com.android.systemui.scene.shared.flag.SceneContainerFlags
+
+class FakeComposeBouncerFlags(
+    private val sceneContainerFlags: SceneContainerFlags,
+    var composeBouncerEnabled: Boolean = false
+) : ComposeBouncerFlags {
+    override fun isComposeBouncerOrSceneContainerEnabled(): Boolean {
+        return sceneContainerFlags.isEnabled() || composeBouncerEnabled
+    }
+
+    @Deprecated(
+        "Avoid using this, this is meant to be used only by the glue code " +
+            "that includes compose bouncer in legacy keyguard.",
+        replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()")
+    )
+    override fun isOnlyComposeBouncerEnabled(): Boolean = composeBouncerEnabled
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
index 99dfe94..6d97238 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt
@@ -21,12 +21,12 @@
 import com.android.systemui.bouncer.domain.interactor.bouncerActionButtonInteractor
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
+import com.android.systemui.bouncer.shared.flag.composeBouncerFlags
 import com.android.systemui.inputmethod.domain.interactor.inputMethodInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import com.android.systemui.user.domain.interactor.selectedUserInteractor
 import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel
 import com.android.systemui.util.mockito.mock
@@ -42,7 +42,7 @@
         simBouncerInteractor = simBouncerInteractor,
         authenticationInteractor = authenticationInteractor,
         selectedUserInteractor = selectedUserInteractor,
-        flags = sceneContainerFlags,
+        flags = composeBouncerFlags,
         selectedUser = userSwitcherViewModel.selectedUser,
         users = userSwitcherViewModel.users,
         userSwitcherMenu = userSwitcherViewModel.menu,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettingsKosmos.kt
new file mode 100644
index 0000000..df6fc41
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettingsKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.systemui.util.settings
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.fakeGlobalSettings: FakeGlobalSettings by Fixture { FakeGlobalSettings() }
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index f31eb44..6ca60be 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -39,7 +39,9 @@
 import android.content.SharedPreferences;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -49,16 +51,22 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
+import android.view.Display;
+import android.view.DisplayInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
 
 import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -102,6 +110,9 @@
     @VisibleForTesting
     static final String WALLPAPER_INFO_STAGE = "wallpaper-info-stage";
 
+    @VisibleForTesting
+    static final String WALLPAPER_BACKUP_DEVICE_INFO_STAGE = "wallpaper-backup-device-info-stage";
+
     static final String EMPTY_SENTINEL = "empty";
     static final String QUOTA_SENTINEL = "quota";
 
@@ -110,6 +121,11 @@
     static final String SYSTEM_GENERATION = "system_gen";
     static final String LOCK_GENERATION = "lock_gen";
 
+    /**
+     * An approximate area threshold to compare device dimension similarity
+     */
+    static final int AREA_THRESHOLD = 50; // TODO: determine appropriate threshold
+
     // If this file exists, it means we exceeded our quota last time
     private File mQuotaFile;
     private boolean mQuotaExceeded;
@@ -121,6 +137,8 @@
     private boolean mSystemHasLiveComponent;
     private boolean mLockHasLiveComponent;
 
+    private DisplayManager mDisplayManager;
+
     @Override
     public void onCreate() {
         if (DEBUG) {
@@ -137,6 +155,8 @@
 
         mBackupManager = new BackupManager(getBaseContext());
         mEventLogger = new WallpaperEventLogger(mBackupManager, /* wallpaperAgent */ this);
+
+        mDisplayManager = getSystemService(DisplayManager.class);
     }
 
     @Override
@@ -175,6 +195,7 @@
             mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null;
             mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null;
 
+            backupDeviceInfoFile(data);
             backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data);
             backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data);
             backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data);
@@ -191,6 +212,50 @@
         }
     }
 
+    /**
+     * This method backs up the device dimension information. The device data will always get
+     * overwritten when triggering a backup
+     */
+    private void backupDeviceInfoFile(FullBackupDataOutput data)
+            throws IOException {
+        final File deviceInfoStage = new File(getFilesDir(), WALLPAPER_BACKUP_DEVICE_INFO_STAGE);
+
+        // save the dimensions of the device with xml formatting
+        Point dimensions = getScreenDimensions();
+        Point secondaryDimensions = getRealSize(getSmallerDisplay());
+
+        deviceInfoStage.createNewFile();
+        FileOutputStream fstream = new FileOutputStream(deviceInfoStage, false);
+        TypedXmlSerializer out = Xml.resolveSerializer(fstream);
+        out.startDocument(null, true);
+        out.startTag(null, "dimensions");
+
+        out.startTag(null, "width");
+        out.text(String.valueOf(dimensions.x));
+        out.endTag(null, "width");
+
+        out.startTag(null, "height");
+        out.text(String.valueOf(dimensions.y));
+        out.endTag(null, "height");
+
+        out.startTag(null, "secondarywidth");
+        out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.x : 0));
+        out.endTag(null, "secondarywidth");
+
+        out.startTag(null, "secondaryheight");
+        out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.y : 0));
+        out.endTag(null, "secondaryheight");
+
+        out.endTag(null, "dimensions");
+        out.endDocument();
+        fstream.flush();
+        FileUtils.sync(fstream);
+        fstream.close();
+
+        if (DEBUG) Slog.v(TAG, "Storing device dimension data");
+        backupFile(deviceInfoStage, data);
+    }
+
     private void backupWallpaperInfoFile(boolean sysOrLockChanged, FullBackupDataOutput data)
             throws IOException {
         final ParcelFileDescriptor wallpaperInfoFd = mWallpaperManager.getWallpaperInfoFile();
@@ -364,9 +429,22 @@
         final File infoStage = new File(filesDir, WALLPAPER_INFO_STAGE);
         final File imageStage = new File(filesDir, SYSTEM_WALLPAPER_STAGE);
         final File lockImageStage = new File(filesDir, LOCK_WALLPAPER_STAGE);
+        final File deviceDimensionsStage = new File(filesDir, WALLPAPER_BACKUP_DEVICE_INFO_STAGE);
         boolean lockImageStageExists = lockImageStage.exists();
 
         try {
+            // Parse the device dimensions of the source device and compare with target to
+            // to identify whether we need to skip the remainder of the restore process
+            Pair<Point, Point> sourceDeviceDimensions = parseDeviceDimensions(
+                    deviceDimensionsStage);
+
+            Point targetDeviceDimensions = getScreenDimensions();
+            if (sourceDeviceDimensions != null
+                    && isSourceDeviceSignificantlySmallerThanTarget(sourceDeviceDimensions.first,
+                    targetDeviceDimensions)) {
+                Slog.d(TAG, "The source device is significantly smaller than target");
+            }
+
             // First parse the live component name so that we know for logging if we care about
             // logging errors with the image restore.
             ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
@@ -400,6 +478,7 @@
             infoStage.delete();
             imageStage.delete();
             lockImageStage.delete();
+            deviceDimensionsStage.delete();
 
             SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
             prefs.edit()
@@ -409,6 +488,66 @@
         }
     }
 
+    /**
+     * This method parses the given file for the backed up device dimensions
+     *
+     * @param deviceDimensions the file which holds the device dimensions
+     * @return the backed up device dimensions
+     */
+    private Pair<Point, Point> parseDeviceDimensions(File deviceDimensions) {
+        int width = 0, height = 0, secondaryHeight = 0, secondaryWidth = 0;
+        try {
+            TypedXmlPullParser parser = Xml.resolvePullParser(
+                    new FileInputStream(deviceDimensions));
+
+            while (parser.next() != XmlPullParser.END_TAG) {
+                if (parser.getEventType() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                String name = parser.getName();
+
+                switch (name) {
+                    case "width":
+                        String widthText = readText(parser);
+                        width = Integer.valueOf(widthText);
+                        break;
+
+                    case "height":
+                        String textHeight = readText(parser);
+                        height = Integer.valueOf(textHeight);
+                        break;
+
+                    case "secondarywidth":
+                        String secondaryWidthText = readText(parser);
+                        secondaryWidth = Integer.valueOf(secondaryWidthText);
+                        break;
+
+                    case "secondaryheight":
+                        String secondaryHeightText = readText(parser);
+                        secondaryHeight = Integer.valueOf(secondaryHeightText);
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return new Pair<>(new Point(width, height), new Point(secondaryWidth, secondaryHeight));
+
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private static String readText(TypedXmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        String result = "";
+        if (parser.next() == XmlPullParser.TEXT) {
+            result = parser.getText();
+            parser.nextTag();
+        }
+        return result;
+    }
+
     @VisibleForTesting
     void updateWallpaperComponent(ComponentName wpService, int which)
             throws IOException {
@@ -500,6 +639,7 @@
             mEventLogger.onLockImageWallpaperRestoreFailed(error);
         }
     }
+
     private Rect parseCropHint(File wallpaperInfo, String sectionTag) {
         Rect cropHint = new Rect();
         try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
@@ -537,7 +677,7 @@
                 if (type != XmlPullParser.START_TAG) continue;
                 String tag = parser.getName();
                 if (!sectionTag.equals(tag)) continue;
-                for (Pair<Integer, String> pair: List.of(
+                for (Pair<Integer, String> pair : List.of(
                         new Pair<>(WallpaperManager.PORTRAIT, "Portrait"),
                         new Pair<>(WallpaperManager.LANDSCAPE, "Landscape"),
                         new Pair<>(WallpaperManager.SQUARE_PORTRAIT, "SquarePortrait"),
@@ -691,6 +831,94 @@
         };
     }
 
+    /**
+     * This method retrieves the dimensions of the largest display of the device
+     *
+     * @return a @{Point} object that contains the dimensions of the largest display on the device
+     */
+    private Point getScreenDimensions() {
+        Point largetDimensions = null;
+        int maxArea = 0;
+
+        for (Display display : getInternalDisplays()) {
+            Point displaySize = getRealSize(display);
+
+            int width = displaySize.x;
+            int height = displaySize.y;
+            int area = width * height;
+
+            if (area > maxArea) {
+                maxArea = area;
+                largetDimensions = displaySize;
+            }
+        }
+
+        return largetDimensions;
+    }
+
+    private Point getRealSize(Display display) {
+        DisplayInfo displayInfo = new DisplayInfo();
+        display.getDisplayInfo(displayInfo);
+        return new Point(displayInfo.logicalWidth, displayInfo.logicalHeight);
+    }
+
+    /**
+     * This method returns the smaller display on a multi-display device
+     *
+     * @return Display that corresponds to the smaller display on a device or null if ther is only
+     * one Display on a device
+     */
+    private Display getSmallerDisplay() {
+        List<Display> internalDisplays = getInternalDisplays();
+        Point largestDisplaySize = getScreenDimensions();
+
+        // Find the first non-matching internal display
+        for (Display display : internalDisplays) {
+            Point displaySize = getRealSize(display);
+            if (displaySize.x != largestDisplaySize.x || displaySize.y != largestDisplaySize.y) {
+                return display;
+            }
+        }
+
+        // If no smaller display found, return null, as there is only a single display
+        return null;
+    }
+
+    /**
+     * This method retrieves the collection of Display objects available in the device.
+     * i.e. non-external displays are ignored
+     *
+     * @return list of displays corresponding to each display in the device
+     */
+    private List<Display> getInternalDisplays() {
+        Display[] allDisplays = mDisplayManager.getDisplays(
+                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
+
+        List<Display> internalDisplays = new ArrayList<>();
+        for (Display display : allDisplays) {
+            if (display.getType() == Display.TYPE_INTERNAL) {
+                internalDisplays.add(display);
+            }
+        }
+        return internalDisplays;
+    }
+
+    /**
+     * This method compares the source and target dimensions, and returns true if there is a
+     * significant difference in area between them and the source dimensions are smaller than the
+     * target dimensions.
+     *
+     * @param sourceDimensions is the dimensions of the source device
+     * @param targetDimensions is the dimensions of the target device
+     */
+    @VisibleForTesting
+    boolean isSourceDeviceSignificantlySmallerThanTarget(Point sourceDimensions,
+            Point targetDimensions) {
+        int rawAreaDelta = (targetDimensions.x * targetDimensions.y)
+                - (sourceDimensions.x * sourceDimensions.y);
+        return rawAreaDelta > AREA_THRESHOLD;
+    }
+
     @VisibleForTesting
     boolean isDeviceInRestore() {
         try {
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index 3ecdf3f..79e7bf0 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -59,6 +59,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
@@ -676,7 +677,7 @@
 
         mWallpaperBackupAgent.onRestoreFinished();
 
-        for (String wallpaper: List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) {
+        for (String wallpaper : List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) {
             DataTypeResult result = getLoggingResult(wallpaper,
                     mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
             assertThat(result).isNotNull();
@@ -840,6 +841,26 @@
         testParseCropHints(testMap);
     }
 
+    @Test
+    public void test_sourceDimensionsAreLargerThanTarget() {
+        // source device is larger than target, expecting to get false
+        Point sourceDimensions = new Point(2208, 1840);
+        Point targetDimensions = new Point(1080, 2092);
+        boolean isSourceSmaller = mWallpaperBackupAgent
+                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
+        assertThat(isSourceSmaller).isEqualTo(false);
+    }
+
+    @Test
+    public void test_sourceDimensionsMuchSmallerThanTarget() {
+        // source device is smaller than target, expecting to get true
+        Point sourceDimensions = new Point(1080, 2092);
+        Point targetDimensions = new Point(2208, 1840);
+        boolean isSourceSmaller = mWallpaperBackupAgent
+                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
+        assertThat(isSourceSmaller).isEqualTo(true);
+    }
+
     private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception {
         assumeTrue(multiCrop());
         mockRestoredStaticWallpaperFile(testMap);
@@ -934,7 +955,7 @@
         TypedXmlSerializer out = Xml.resolveSerializer(fstream);
         out.startDocument(null, true);
         out.startTag(null, "wp");
-        for (Map.Entry<Integer, Rect> entry: crops.entrySet()) {
+        for (Map.Entry<Integer, Rect> entry : crops.entrySet()) {
             String orientation = switch (entry.getKey()) {
                 case WallpaperManager.PORTRAIT -> "Portrait";
                 case WallpaperManager.LANDSCAPE -> "Landscape";
diff --git a/proto/src/criticalevents/critical_event_log.proto b/proto/src/criticalevents/critical_event_log.proto
index cffcd09..71d291a 100644
--- a/proto/src/criticalevents/critical_event_log.proto
+++ b/proto/src/criticalevents/critical_event_log.proto
@@ -61,6 +61,12 @@
     NativeCrash native_crash = 6;
     SystemServerStarted system_server_started = 7;
     InstallPackages install_packages = 8;
+    ExcessiveBinderCalls excessive_binder_calls = 9;
+  }
+
+  message ExcessiveBinderCalls {
+    // The uid sending many calls.
+    optional int32 uid = 1;
   }
 
   message InstallPackages {}
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 41a4a1a..e535f0a 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -77,6 +77,7 @@
     libs: [
         "android.test.mock",
         "framework-minus-apex.ravenwood",
+        "ravenwood-framework",
         "services.core.ravenwood",
         "junit",
     ],
@@ -102,6 +103,21 @@
     visibility: ["//visibility:public"],
 }
 
+// Library used to publish a handful of `android.ravenwood` APIs into
+// the Ravenwood BCP; we don't want to publish these APIs into the BCP
+// on physical devices, which is why this is a separate library
+java_library {
+    name: "ravenwood-framework",
+    srcs: [
+        "framework-src/**/*.java",
+    ],
+    libs: [
+        "framework-minus-apex.ravenwood",
+    ],
+    sdk_version: "core_current",
+    visibility: ["//visibility:public"],
+}
+
 java_host_for_device {
     name: "androidx.test.monitor-for-device",
     libs: [
diff --git a/ravenwood/framework-src/android/ravenwood/example/BlueManager.java b/ravenwood/framework-src/android/ravenwood/example/BlueManager.java
new file mode 100644
index 0000000..fc713b1
--- /dev/null
+++ b/ravenwood/framework-src/android/ravenwood/example/BlueManager.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.ravenwood.example;
+
+import android.annotation.SystemService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+@SystemService(BlueManager.SERVICE_NAME)
+public class BlueManager {
+    public static final String SERVICE_NAME = "example_blue";
+
+    public String getInterfaceDescriptor() {
+        try {
+            return ServiceManager.getService(SERVICE_NAME).getInterfaceDescriptor();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/ravenwood/framework-src/android/ravenwood/example/RedManager.java b/ravenwood/framework-src/android/ravenwood/example/RedManager.java
new file mode 100644
index 0000000..381a901
--- /dev/null
+++ b/ravenwood/framework-src/android/ravenwood/example/RedManager.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.ravenwood.example;
+
+import android.annotation.SystemService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+@SystemService(RedManager.SERVICE_NAME)
+public class RedManager {
+    public static final String SERVICE_NAME = "example_red";
+
+    public String getInterfaceDescriptor() {
+        try {
+            return ServiceManager.getService(SERVICE_NAME).getInterfaceDescriptor();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
index c17d090..109ef76 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
@@ -26,6 +26,8 @@
 import android.os.PermissionEnforcer;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.ravenwood.example.BlueManager;
+import android.ravenwood.example.RedManager;
 import android.test.mock.MockContext;
 import android.util.ArrayMap;
 import android.util.Singleton;
@@ -53,16 +55,23 @@
         mPackageName = packageName;
         mMainThread = mainThread;
 
+        // Services provided by a typical shipping device
         registerService(ClipboardManager.class,
-                Context.CLIPBOARD_SERVICE, asSingleton(() ->
+                Context.CLIPBOARD_SERVICE, memoize(() ->
                         new ClipboardManager(this, getMainThreadHandler())));
         registerService(PermissionEnforcer.class,
                 Context.PERMISSION_ENFORCER_SERVICE, () -> mEnforcer);
         registerService(SerialManager.class,
-                Context.SERIAL_SERVICE, asSingleton(() ->
+                Context.SERIAL_SERVICE, memoize(() ->
                         new SerialManager(this, ISerialManager.Stub.asInterface(
                                 ServiceManager.getService(Context.SERIAL_SERVICE)))
                 ));
+
+        // Additional services we provide for testing purposes
+        registerService(BlueManager.class,
+                BlueManager.SERVICE_NAME, memoize(() -> new BlueManager()));
+        registerService(RedManager.class,
+                RedManager.SERVICE_NAME, memoize(() -> new RedManager()));
     }
 
     @Override
@@ -143,9 +152,12 @@
     }
 
     /**
-     * Wrap the given {@link Supplier} to become a memoized singleton.
+     * Wrap the given {@link Supplier} to become memoized.
+     *
+     * The underlying {@link Supplier} will only be invoked once, and that result will be cached
+     * and returned for any future requests.
      */
-    private static <T> Supplier<T> asSingleton(ThrowingSupplier<T> supplier) {
+    private static <T> Supplier<T> memoize(ThrowingSupplier<T> supplier) {
         final Singleton<T> singleton = new Singleton<>() {
             @Override
             protected T create() {
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
index 3de96c0..cd6b61d 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
@@ -19,13 +19,19 @@
 import android.content.ClipboardManager;
 import android.hardware.SerialManager;
 import android.os.SystemClock;
+import android.ravenwood.example.BlueManager;
+import android.ravenwood.example.RedManager;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.utils.TimingsTraceAndSlog;
 
+import java.util.List;
+import java.util.Set;
+
 public class RavenwoodSystemServer {
     /**
      * Set of services that we know how to provide under Ravenwood. We keep this set distinct
@@ -37,16 +43,21 @@
      */
     private static final ArrayMap<Class<?>, String> sKnownServices = new ArrayMap<>();
 
-    // TODO: expand SystemService API to support dependency expression, so we don't need test
-    // authors to exhaustively declare all transitive services
-
     static {
+        // Services provided by a typical shipping device
         sKnownServices.put(ClipboardManager.class,
                 "com.android.server.FakeClipboardService$Lifecycle");
         sKnownServices.put(SerialManager.class,
                 "com.android.server.SerialService$Lifecycle");
+
+        // Additional services we provide for testing purposes
+        sKnownServices.put(BlueManager.class,
+                "com.android.server.example.BlueManagerService$Lifecycle");
+        sKnownServices.put(RedManager.class,
+                "com.android.server.example.RedManagerService$Lifecycle");
     }
 
+    private static Set<Class<?>> sStartedServices;
     private static TimingsTraceAndSlog sTimings;
     private static SystemServiceManager sServiceManager;
 
@@ -54,6 +65,7 @@
         // Avoid overhead if no services required
         if (rule.mServicesRequired.isEmpty()) return;
 
+        sStartedServices = new ArraySet<>();
         sTimings = new TimingsTraceAndSlog();
         sServiceManager = new SystemServiceManager(rule.mContext);
         sServiceManager.setStartInfo(false,
@@ -61,17 +73,7 @@
                 SystemClock.uptimeMillis());
         LocalServices.addService(SystemServiceManager.class, sServiceManager);
 
-        for (Class<?> service : rule.mServicesRequired) {
-            final String target = sKnownServices.get(service);
-            if (target == null) {
-                throw new RuntimeException("The requested service " + service
-                        + " is not yet supported under the Ravenwood deviceless testing "
-                        + "environment; consider requesting support from the API owner or "
-                        + "consider using Mockito; more details at go/ravenwood-docs");
-            } else {
-                sServiceManager.startService(target);
-            }
-        }
+        startServices(rule.mServicesRequired);
         sServiceManager.sealStartedServices();
 
         // TODO: expand to include additional boot phases when relevant
@@ -85,5 +87,26 @@
         LocalServices.removeServiceForTest(SystemServiceManager.class);
         sServiceManager = null;
         sTimings = null;
+        sStartedServices = null;
+    }
+
+    private static void startServices(List<Class<?>> serviceClasses) {
+        for (Class<?> serviceClass : serviceClasses) {
+            // Quietly ignore duplicate requests if service already started
+            if (sStartedServices.contains(serviceClass)) continue;
+            sStartedServices.add(serviceClass);
+
+            final String serviceName = sKnownServices.get(serviceClass);
+            if (serviceName == null) {
+                throw new RuntimeException("The requested service " + serviceClass
+                        + " is not yet supported under the Ravenwood deviceless testing "
+                        + "environment; consider requesting support from the API owner or "
+                        + "consider using Mockito; more details at go/ravenwood-docs");
+            }
+
+            // Start service and then depth-first traversal of any dependencies
+            final SystemService instance = sServiceManager.startService(serviceName);
+            startServices(instance.getDependencies());
+        }
     }
 }
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index a520d4c..52ea340 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -35,6 +35,8 @@
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
@@ -127,7 +129,7 @@
 
     final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
 
-    final ArraySet<Class<?>> mServicesRequired = new ArraySet<>();
+    final List<Class<?>> mServicesRequired = new ArrayList<>();
 
     volatile Context mContext;
     volatile Instrumentation mInstrumentation;
diff --git a/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java b/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java
new file mode 100644
index 0000000..efe468d
--- /dev/null
+++ b/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.ravenwood;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.ravenwood.RavenwoodRule;
+import android.ravenwood.example.BlueManager;
+import android.ravenwood.example.RedManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RavenwoodServicesDependenciesTest {
+    // NOTE: we carefully only ask for RedManager here, and rely on Ravenwood internals to spin
+    // up the implicit dependency on BlueManager
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+            .setProcessSystem()
+            .setServicesRequired(RedManager.class)
+            .build();
+
+    @Test
+    public void testDirect() {
+        final RedManager red = mRavenwood.getContext().getSystemService(
+                RedManager.class);
+        assertEquals("blue+red", red.getInterfaceDescriptor());
+    }
+
+    @Test
+    public void testIndirect() {
+        final BlueManager blue = mRavenwood.getContext().getSystemService(
+                BlueManager.class);
+        assertEquals("blue", blue.getInterfaceDescriptor());
+    }
+}
diff --git a/sax/tests/saxtests/Android.bp b/sax/tests/saxtests/Android.bp
index cbd19c3..446ee93 100644
--- a/sax/tests/saxtests/Android.bp
+++ b/sax/tests/saxtests/Android.bp
@@ -15,6 +15,9 @@
         "android.test.runner",
         "android.test.base",
     ],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+    ],
     platform_apis: true,
 }
diff --git a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
index a68fc9a..2a08f54 100644
--- a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
+++ b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
@@ -17,18 +17,16 @@
 package android.sax;
 
 import android.graphics.Bitmap;
-import android.sax.Element;
-import android.sax.ElementListener;
-import android.sax.EndTextElementListener;
-import android.sax.RootElement;
-import android.sax.StartElementListener;
-import android.sax.TextElementListener;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.Xml;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.SmallTest;
+
+import com.android.frameworks.saxtests.R;
 import com.android.internal.util.XmlUtils;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -40,8 +38,6 @@
 import java.io.InputStream;
 import java.time.Instant;
 
-import com.android.frameworks.saxtests.R;
-
 public class SafeSaxTest extends AndroidTestCase {
 
     private static final String TAG = SafeSaxTest.class.getName();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 43c018c..cbb66dc 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4659,8 +4659,8 @@
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ShellCallback callback,
             ResultReceiver resultReceiver) {
-        new AccessibilityShellCommand(this, mSystemActionPerformer).exec(this, in, out, err, args,
-                callback, resultReceiver);
+        new AccessibilityShellCommand(mContext, this, mSystemActionPerformer)
+                .exec(this, in, out, err, args, callback, resultReceiver);
     }
 
     private final class InteractionBridge {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
index 8cf5547..4908032 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
@@ -16,8 +16,10 @@
 
 package com.android.server.accessibility;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
+import android.content.Context;
 import android.os.Binder;
 import android.os.Process;
 import android.os.ShellCommand;
@@ -26,18 +28,27 @@
 import com.android.server.LocalServices;
 import com.android.server.wm.WindowManagerInternal;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 
 /**
  * Shell command implementation for the accessibility manager service
  */
 final class AccessibilityShellCommand extends ShellCommand {
-    final @NonNull AccessibilityManagerService mService;
-    final @NonNull SystemActionPerformer mSystemActionPerformer;
-    final @NonNull WindowManagerInternal mWindowManagerService;
+    @NonNull
+    final Context mContext;
+    @NonNull
+    final AccessibilityManagerService mService;
+    @NonNull
+    final SystemActionPerformer mSystemActionPerformer;
+    @NonNull
+    final WindowManagerInternal mWindowManagerService;
 
-    AccessibilityShellCommand(@NonNull AccessibilityManagerService service,
+    AccessibilityShellCommand(@NonNull Context context,
+            @NonNull AccessibilityManagerService service,
             @NonNull SystemActionPerformer systemActionPerformer) {
+        mContext = context;
         mService = service;
         mSystemActionPerformer = systemActionPerformer;
         mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
@@ -61,6 +72,8 @@
             case "start-trace":
             case "stop-trace":
                 return mService.getTraceManager().onShellCommand(cmd, this);
+            case "check-hidraw":
+                return checkHidraw();
         }
         return -1;
     }
@@ -106,6 +119,67 @@
         return -1;
     }
 
+    private int checkHidraw() {
+        mContext.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY,
+                "Missing MANAGE_ACCESSIBILITY permission");
+        String subcommand = getNextArgRequired();
+        File hidrawNode = new File(getNextArgRequired());
+        switch (subcommand) {
+            case "read" -> {
+                return checkHidrawRead(hidrawNode);
+            }
+            case "write" -> {
+                return checkHidrawWrite(hidrawNode);
+            }
+            case "descriptor" -> {
+                return checkHidrawDescriptor(hidrawNode);
+            }
+            default -> {
+                getErrPrintWriter().print("Unknown subcommand " + subcommand);
+                return -1;
+            }
+        }
+    }
+
+    private int checkHidrawRead(File hidrawNode) {
+        if (!hidrawNode.canRead()) {
+            getErrPrintWriter().println("Unable to read from " + hidrawNode);
+            return -1;
+        }
+        // Tests executing this command using UiAutomation#executeShellCommand will not receive
+        // the command's exit value, so print the path to stdout to indicate success.
+        getOutPrintWriter().print(hidrawNode.getAbsolutePath());
+        return 0;
+    }
+
+    private int checkHidrawWrite(File hidrawNode) {
+        if (!hidrawNode.canWrite()) {
+            getErrPrintWriter().println("Unable to write to " + hidrawNode);
+            return -1;
+        }
+        // Tests executing this command using UiAutomation#executeShellCommand will not receive
+        // the command's exit value, so print the path to stdout to indicate success.
+        getOutPrintWriter().print(hidrawNode.getAbsolutePath());
+        return 0;
+    }
+
+    private int checkHidrawDescriptor(File hidrawNode) {
+        BrailleDisplayConnection.BrailleDisplayScanner scanner =
+                BrailleDisplayConnection.createScannerForShell();
+        byte[] descriptor = scanner.getDeviceReportDescriptor(hidrawNode.toPath());
+        if (descriptor == null) {
+            getErrPrintWriter().println("Unable to read descriptor for " + hidrawNode);
+            return -1;
+        }
+        try {
+            // Print the descriptor bytes to stdout.
+            getRawOutputStream().write(descriptor);
+            return 0;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     private Integer parseUserId() {
         final String option = getNextOption();
         if (option != null) {
@@ -131,6 +205,8 @@
         pw.println("    Get whether binding to services provided by instant apps is allowed.");
         pw.println("  call-system-action <ACTION_ID>");
         pw.println("    Calls the system action with the given action id.");
+        pw.println("  check-hidraw [read|write|descriptor] <HIDRAW_NODE_PATH>");
+        pw.println("    Checks if the system can perform various actions on the HIDRAW node.");
         mService.getTraceManager().onHelp(pw);
     }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
index 40b6ff0..8b41873 100644
--- a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
@@ -116,6 +116,13 @@
     }
 
     /**
+     * Used for `cmd accessibility` to check hidraw access.
+     */
+    static BrailleDisplayScanner createScannerForShell() {
+        return getDefaultNativeScanner(new DefaultNativeInterface());
+    }
+
+    /**
      * Interface to scan for properties of connected Braille displays.
      *
      * <p>Helps simplify testing Braille Display APIs using test data without requiring
@@ -125,7 +132,6 @@
      * @see #getDefaultNativeScanner
      * @see #setTestData
      */
-    @VisibleForTesting
     interface BrailleDisplayScanner {
         Collection<Path> getHidrawNodePaths(@NonNull Path directory);
 
@@ -441,7 +447,7 @@
      * from HIDRAW nodes and perform ioctls using the provided {@link NativeInterface}.
      */
     @VisibleForTesting
-    BrailleDisplayScanner getDefaultNativeScanner(@NonNull NativeInterface nativeInterface) {
+    static BrailleDisplayScanner getDefaultNativeScanner(@NonNull NativeInterface nativeInterface) {
         Objects.requireNonNull(nativeInterface);
         return new BrailleDisplayScanner() {
             private static final String HIDRAW_DEVICE_GLOB = "hidraw*";
@@ -576,7 +582,7 @@
     }
 
     /** Native interface that actually calls native HIDRAW ioctls. */
-    private class DefaultNativeInterface implements NativeInterface {
+    private static class DefaultNativeInterface implements NativeInterface {
         @Override
         public int getHidrawDescSize(int fd) {
             return nativeGetHidrawDescSize(fd);
@@ -598,11 +604,11 @@
         }
     }
 
-    private native int nativeGetHidrawDescSize(int fd);
+    private static native int nativeGetHidrawDescSize(int fd);
 
-    private native byte[] nativeGetHidrawDesc(int fd, int descSize);
+    private static native byte[] nativeGetHidrawDesc(int fd, int descSize);
 
-    private native String nativeGetHidrawUniq(int fd);
+    private static native String nativeGetHidrawUniq(int fd);
 
-    private native int nativeGetHidrawBusType(int fd);
+    private static native int nativeGetHidrawBusType(int fd);
 }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index e666442..5c1007c 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -167,6 +167,9 @@
     // List of packages that have RestoreAnyVersion set to true but do not support  V-> U downgrade.
     private List<String> mVToUDenylist;
 
+    // Whether we have already initialised the V to U allowlist/denylist
+    private Boolean mAreVToUListsSet = false;
+
     // Key/value: bookkeeping about staged data and files for agent access
     private File mBackupDataName;
     private File mStageName;
@@ -235,18 +238,6 @@
                         backupManagerService.getAgentTimeoutParameters(),
                         "Timeout parameters cannot be null");
         mBackupEligibilityRules = backupEligibilityRules;
-        mVToUAllowlist =
-            createVToUList(
-                Settings.Secure.getStringForUser(
-                    backupManagerService.getContext().getContentResolver(),
-                    Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
-                    mUserId));
-        mVToUDenylist =
-            createVToUList(
-                Settings.Secure.getStringForUser(
-                    backupManagerService.getContext().getContentResolver(),
-                    Settings.Secure.V_TO_U_RESTORE_DENYLIST,
-                    mUserId));
 
         if (targetPackage != null) {
             // Single package restore
@@ -661,7 +652,23 @@
                 // installed.  If the app has not declared that it is prepared to
                 // handle this case, we do not attempt the restore.
                 if (mIsSystemRestore
-                    && isVToUDowngrade(mPmAgent.getSourceSdk(), android.os.Build.VERSION.SDK_INT)) {
+                        && isVToUDowngrade(mPmAgent.getSourceSdk(),
+                        android.os.Build.VERSION.SDK_INT)) {
+                    if (!mAreVToUListsSet) {
+                        mVToUAllowlist =
+                                createVToUList(
+                                        Settings.Secure.getStringForUser(
+                                            backupManagerService.getContext().getContentResolver(),
+                                            Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
+                                            mUserId));
+                        mVToUDenylist =
+                                createVToUList(
+                                        Settings.Secure.getStringForUser(
+                                            backupManagerService.getContext().getContentResolver(),
+                                            Settings.Secure.V_TO_U_RESTORE_DENYLIST,
+                                            mUserId));
+                        mAreVToUListsSet = true;
+                    }
                     if (isPackageEligibleForVToURestore(mCurrentPackage)) {
                         Slog.i(TAG, "Package " + pkgName
                                 + " is eligible for V to U downgrade scenario");
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index d4ff699..6b5ba96 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -50,7 +50,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityThread;
-import android.app.admin.DevicePolicyManagerInternal;
+import android.app.admin.DevicePolicyCache;
 import android.app.assist.ActivityId;
 import android.content.ComponentName;
 import android.content.ContentCaptureOptions;
@@ -940,7 +940,7 @@
         return new ContentProtectionConsentManager(
                 BackgroundThread.getHandler(),
                 getContext().getContentResolver(),
-                LocalServices.getService(DevicePolicyManagerInternal.class));
+                DevicePolicyCache.getInstance());
     }
 
     @Nullable
diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java
index 488a51a..9aa5d2f 100644
--- a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java
+++ b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java
@@ -16,8 +16,13 @@
 
 package com.android.server.contentprotection;
 
+import static android.view.contentprotection.flags.Flags.manageDevicePolicyEnabled;
+
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyCache;
+import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ContentResolver;
 import android.database.ContentObserver;
@@ -28,6 +33,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
 
 /**
  * Manages consent for content protection.
@@ -45,6 +51,8 @@
 
     @NonNull private final ContentResolver mContentResolver;
 
+    @NonNull private final DevicePolicyCache mDevicePolicyCache;
+
     @NonNull private final DevicePolicyManagerInternal mDevicePolicyManagerInternal;
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -53,54 +61,98 @@
 
     private volatile boolean mCachedPackageVerifierConsent;
 
-    private volatile boolean mCachedContentProtectionConsent;
+    private volatile boolean mCachedContentProtectionUserConsent;
 
     public ContentProtectionConsentManager(
             @NonNull Handler handler,
             @NonNull ContentResolver contentResolver,
-            @NonNull DevicePolicyManagerInternal devicePolicyManagerInternal) {
+            @NonNull DevicePolicyCache devicePolicyCache) {
         mContentResolver = contentResolver;
-        mDevicePolicyManagerInternal = devicePolicyManagerInternal;
+        mDevicePolicyCache = devicePolicyCache;
+        mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
         mContentObserver = new SettingsObserver(handler);
 
-        contentResolver.registerContentObserver(
-                Settings.Global.getUriFor(KEY_PACKAGE_VERIFIER_USER_CONSENT),
-                /* notifyForDescendants= */ false,
-                mContentObserver,
-                UserHandle.USER_ALL);
+        registerSettingsGlobalObserver(KEY_PACKAGE_VERIFIER_USER_CONSENT);
+        registerSettingsGlobalObserver(KEY_CONTENT_PROTECTION_USER_CONSENT);
+        readPackageVerifierConsentGranted();
+        readContentProtectionUserConsentGranted();
+    }
 
-        mCachedPackageVerifierConsent = isPackageVerifierConsentGranted();
-        mCachedContentProtectionConsent = isContentProtectionConsentGranted();
+    /** Returns true if the consent is ultimately granted. */
+    public boolean isConsentGranted(@UserIdInt int userId) {
+        return mCachedPackageVerifierConsent && isContentProtectionConsentGranted(userId);
     }
 
     /**
-     * Returns true if all the consents are granted
+     * Not always cached internally and can be expensive, when possible prefer to use {@link
+     * #mCachedPackageVerifierConsent} instead.
      */
-    public boolean isConsentGranted(@UserIdInt int userId) {
-        return mCachedPackageVerifierConsent
-                && mCachedContentProtectionConsent
-                && !isUserOrganizationManaged(userId);
-    }
-
     private boolean isPackageVerifierConsentGranted() {
-        // Not always cached internally
         return Settings.Global.getInt(
                         mContentResolver, KEY_PACKAGE_VERIFIER_USER_CONSENT, /* def= */ 0)
                 >= 1;
     }
 
-    private boolean isContentProtectionConsentGranted() {
-        // Not always cached internally
+    /**
+     * Not always cached internally and can be expensive, when possible prefer to use {@link
+     * #mCachedContentProtectionUserConsent} instead.
+     */
+    private boolean isContentProtectionUserConsentGranted() {
         return Settings.Global.getInt(
                         mContentResolver, KEY_CONTENT_PROTECTION_USER_CONSENT, /* def= */ 0)
                 >= 0;
     }
 
+    private void readPackageVerifierConsentGranted() {
+        mCachedPackageVerifierConsent = isPackageVerifierConsentGranted();
+    }
+
+    private void readContentProtectionUserConsentGranted() {
+        mCachedContentProtectionUserConsent = isContentProtectionUserConsentGranted();
+    }
+
+    /** Always cached internally, cheap and safe to use. */
     private boolean isUserOrganizationManaged(@UserIdInt int userId) {
-        // Cached internally
         return mDevicePolicyManagerInternal.isUserOrganizationManaged(userId);
     }
 
+    /** Always cached internally, cheap and safe to use. */
+    private boolean isContentProtectionPolicyGranted(@UserIdInt int userId) {
+        if (!manageDevicePolicyEnabled()) {
+            return false;
+        }
+
+        @DevicePolicyManager.ContentProtectionPolicy
+        int policy = mDevicePolicyCache.getContentProtectionPolicy(userId);
+
+        return switch (policy) {
+            case DevicePolicyManager.CONTENT_PROTECTION_ENABLED -> true;
+            case DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY ->
+                    mCachedContentProtectionUserConsent;
+            default -> false;
+        };
+    }
+
+    /** Always cached internally, cheap and safe to use. */
+    private boolean isContentProtectionConsentGranted(@UserIdInt int userId) {
+        if (!manageDevicePolicyEnabled()) {
+            return mCachedContentProtectionUserConsent && !isUserOrganizationManaged(userId);
+        }
+
+        return isUserOrganizationManaged(userId)
+                ? isContentProtectionPolicyGranted(userId)
+                : mCachedContentProtectionUserConsent;
+    }
+
+    private void registerSettingsGlobalObserver(@NonNull String key) {
+        registerSettingsObserver(Settings.Global.getUriFor(key));
+    }
+
+    private void registerSettingsObserver(@NonNull Uri uri) {
+        mContentResolver.registerContentObserver(
+                uri, /* notifyForDescendants= */ false, mContentObserver, UserHandle.USER_ALL);
+    }
+
     private final class SettingsObserver extends ContentObserver {
 
         SettingsObserver(Handler handler) {
@@ -108,17 +160,20 @@
         }
 
         @Override
-        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
+        public void onChange(boolean selfChange, @Nullable Uri uri, @UserIdInt int userId) {
+            if (uri == null) {
+                return;
+            }
             final String property = uri.getLastPathSegment();
             if (property == null) {
                 return;
             }
             switch (property) {
                 case KEY_PACKAGE_VERIFIER_USER_CONSENT:
-                    mCachedPackageVerifierConsent = isPackageVerifierConsentGranted();
+                    readPackageVerifierConsentGranted();
                     return;
                 case KEY_CONTENT_PROTECTION_USER_CONSENT:
-                    mCachedContentProtectionConsent = isContentProtectionConsentGranted();
+                    readContentProtectionUserConsentGranted();
                     return;
                 default:
                     Slog.w(TAG, "Ignoring unexpected property: " + property);
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 7dc9f10..4de85fe 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -39,7 +39,9 @@
 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;
 
 /**
  * The base class for services running in the system process. Override and implement
@@ -135,6 +137,7 @@
     public @interface BootPhase {}
 
     private final Context mContext;
+    private final List<Class<?>> mDependencies;
 
     /**
      * Class representing user in question in the lifecycle callbacks.
@@ -332,7 +335,28 @@
      * @param context The system server context.
      */
     public SystemService(@NonNull Context context) {
+        this(context, Collections.emptyList());
+    }
+
+    /**
+     * Initializes the system service.
+     * <p>
+     * Subclasses must define a single argument constructor that accepts the context
+     * and passes it to super.
+     * </p>
+     *
+     * @param context The system server context.
+     * @param dependencies The list of dependencies that this service requires to operate.
+     *                     Currently only used by the Ravenwood deviceless testing environment to
+     *                     understand transitive dependencies needed to support a specific test.
+     *                     For example, including {@code PowerManager.class} here indicates that
+     *                     this service requires the {@code PowerManager} and/or {@code
+     *                     PowerManagerInternal} APIs to function.
+     * @hide
+     */
+    public SystemService(@NonNull Context context, @NonNull List<Class<?>> dependencies) {
         mContext = context;
+        mDependencies = Objects.requireNonNull(dependencies);
     }
 
     /**
@@ -356,6 +380,22 @@
     }
 
     /**
+     * Get the list of dependencies that this service requires to operate.
+     *
+     * Currently only used by the Ravenwood deviceless testing environment to understand transitive
+     * dependencies needed to support a specific test.
+     *
+     * For example, including {@code PowerManager.class} here indicates that this service
+     * requires the {@code PowerManager} and/or {@code PowerManagerInternal} APIs to function.
+     *
+     * @hide
+     */
+    @NonNull
+    public final List<Class<?>> getDependencies() {
+        return mDependencies;
+    }
+
+    /**
      * Returns true if the system is running in safe mode.
      * TODO: we should define in which phase this becomes valid
      *
diff --git a/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java
index 96fee929..0e0bf81 100644
--- a/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java
+++ b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java
@@ -20,6 +20,7 @@
 
 import android.app.KeyguardManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.biometrics.AuthenticationStateListener;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
@@ -187,6 +188,11 @@
     }
 
     private void reportAuthAttempt(int authType, boolean success, int userId) {
+        // Disable adaptive auth for automotive devices by default
+        if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+            return;
+        }
+
         if (success) {
             // Deleting the entry effectively resets the counter of failed attempts for the user
             mFailedAttemptsForUser.delete(userId);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7d3af99b..b8e09cc 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -372,15 +372,6 @@
     @Overridable
     public static final long FGS_BOOT_COMPLETED_RESTRICTIONS = 296558535L;
 
-    /**
-     * Disables foreground service background starts in System Alert Window for all types
-     * unless it already has a System Overlay Window.
-     */
-    @ChangeId
-    @EnabledSince(targetSdkVersion = VERSION_CODES.VANILLA_ICE_CREAM)
-    @Overridable
-    public static final long FGS_SAW_RESTRICTIONS = 319471980L;
-
     final ActivityManagerService mAm;
 
     // Maximum number of services that we allow to start in the background
@@ -8535,31 +8526,10 @@
             }
         }
 
-        // The flag being enabled isn't enough to deny background start: we need to also check
-        // if there is a system alert UI present.
         if (ret == REASON_DENIED) {
-            // Flag check: are we disabling SAW FGS background starts?
-            final boolean shouldDisableSaw = Flags.fgsDisableSaw()
-                    && CompatChanges.isChangeEnabled(FGS_BOOT_COMPLETED_RESTRICTIONS, callingUid);
-            if (shouldDisableSaw) {
-                final ProcessRecord processRecord = mAm
-                        .getProcessRecordLocked(targetService.processName,
-                        targetService.appInfo.uid);
-                if (processRecord != null) {
-                    if (processRecord.mState.hasOverlayUi()) {
-                        if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
-                                callingPackage)) {
-                            ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
-                        }
-                    }
-                } else {
-                    Slog.e(TAG, "Could not find process record for SAW check");
-                }
-            } else {
-                if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
-                        callingPackage)) {
-                    ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
-                }
+            if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
+                    callingPackage)) {
+                ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e222878..663ba8a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9028,6 +9028,7 @@
                         Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
                                 + Process.myUid());
                         BinderProxy.dumpProxyDebugInfo();
+                        CriticalEventLog.getInstance().logExcessiveBinderCalls(uid);
                         if (uid == Process.SYSTEM_UID) {
                             Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
                         } else {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 34ba7f0..3abfe082 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1468,7 +1468,7 @@
 
         // Send PROFILE_INACCESSIBLE broadcast if a profile was stopped
         final UserInfo userInfo = getUserInfo(userId);
-        if (userInfo.isProfile()) {
+        if (userInfo != null && userInfo.isProfile()) {
             UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
             if (parent != null) {
                 broadcastProfileAccessibleStateChanged(userId, parent.id,
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index e955b00..c06bdf9 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -23,13 +23,6 @@
 }
 
 flag {
-    name: "fgs_disable_saw"
-    namespace: "backstage_power"
-    description: "Disable System Alert Window FGS start"
-    bug: "296558535"
-}
-
-flag {
     name: "bfgs_managed_network_access"
     namespace: "backstage_power"
     description: "Restrict network access for certain applications in BFGS process state"
@@ -60,3 +53,10 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "backstage_power"
+    name: "defer_outgoing_bcasts"
+    description: "Defer outgoing broadcasts from processes in freezable state"
+    bug: "327496592"
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 007b746..fb826c8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -24,6 +24,7 @@
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.ComponentInfoInternal;
@@ -39,6 +40,7 @@
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.face.IFaceServiceReceiver;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -64,6 +66,7 @@
 import com.android.server.biometrics.sensors.BaseClientMonitor;
 import com.android.server.biometrics.sensors.BiometricScheduler;
 import com.android.server.biometrics.sensors.BiometricStateCallback;
+import com.android.server.biometrics.sensors.BiometricUtils;
 import com.android.server.biometrics.sensors.ClientMonitorCallback;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
 import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
@@ -359,6 +362,17 @@
                     null /* callback */);
         }
 
+        if (Build.isDebuggable()) {
+            BiometricUtils<Face> utils = FaceUtils.getInstance(
+                    mFaceSensors.keyAt(0));
+            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
+                List<Face> enrollments = utils.getBiometricsForUser(mContext, user.id);
+                Slog.d(getTag(), "Expecting enrollments for user " + user.id + ": "
+                        + enrollments.stream().map(
+                        BiometricAuthenticator.Identifier::getBiometricId).toList());
+            }
+        }
+
         return mDaemon;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index a104cf4..c04c47e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.content.res.TypedArray;
+import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IInvalidationCallback;
@@ -46,6 +47,7 @@
 import android.hardware.fingerprint.ISidefpsController;
 import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -71,6 +73,7 @@
 import com.android.server.biometrics.sensors.BaseClientMonitor;
 import com.android.server.biometrics.sensors.BiometricScheduler;
 import com.android.server.biometrics.sensors.BiometricStateCallback;
+import com.android.server.biometrics.sensors.BiometricUtils;
 import com.android.server.biometrics.sensors.ClientMonitorCallback;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
 import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
@@ -382,6 +385,17 @@
                     null /* callback */);
         }
 
+        if (Build.isDebuggable()) {
+            BiometricUtils<Fingerprint> utils = FingerprintUtils.getInstance(
+                    mFingerprintSensors.keyAt(0));
+            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
+                List<Fingerprint> enrollments = utils.getBiometricsForUser(mContext, user.id);
+                Slog.d(getTag(), "Expecting enrollments for user " + user.id + ": "
+                        + enrollments.stream().map(
+                                BiometricAuthenticator.Identifier::getBiometricId).toList());
+            }
+        }
+
         return mDaemon;
     }
 
diff --git a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
index 816c349..036284f 100644
--- a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
+++ b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
@@ -30,6 +30,7 @@
 import com.android.server.criticalevents.nano.CriticalEventProto.AppNotResponding;
 import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog;
 import com.android.server.criticalevents.nano.CriticalEventProto.InstallPackages;
+import com.android.server.criticalevents.nano.CriticalEventProto.ExcessiveBinderCalls;
 import com.android.server.criticalevents.nano.CriticalEventProto.JavaCrash;
 import com.android.server.criticalevents.nano.CriticalEventProto.NativeCrash;
 import com.android.server.criticalevents.nano.CriticalEventProto.SystemServerStarted;
@@ -143,6 +144,15 @@
         return System.currentTimeMillis();
     }
 
+   /** Logs when a uid sends an excessive number of binder calls. */
+    public void logExcessiveBinderCalls(int uid) {
+        CriticalEventProto event = new CriticalEventProto();
+        ExcessiveBinderCalls calls = new ExcessiveBinderCalls();
+        calls.uid = uid;
+        event.setExcessiveBinderCalls(calls);
+        log(event);
+    }
+
     /** Logs when one or more packages are installed. */
     public void logInstallPackagesStarted() {
         CriticalEventProto event = new CriticalEventProto();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 23ca814..76f3035 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1725,6 +1725,7 @@
         mTempBrightnessEvent.setBrightness(brightnessState);
         mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
         mTempBrightnessEvent.setDisplayState(state);
+        mTempBrightnessEvent.setDisplayPolicy(mPowerRequest.policy);
         mTempBrightnessEvent.setReason(mBrightnessReason);
         mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
         mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
index 5423b74..82b401a 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
@@ -16,6 +16,9 @@
 
 package com.android.server.display.brightness;
 
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.policyToString;
+
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessModeToString;
 
@@ -46,6 +49,7 @@
     private int mDisplayId;
     private String mPhysicalDisplayId;
     private int mDisplayState;
+    private int mDisplayPolicy;
     private long mTime;
     private float mLux;
     private float mPreThresholdLux;
@@ -85,6 +89,7 @@
         mDisplayId = that.getDisplayId();
         mPhysicalDisplayId = that.getPhysicalDisplayId();
         mDisplayState = that.mDisplayState;
+        mDisplayPolicy = that.mDisplayPolicy;
         mTime = that.getTime();
         // Lux values
         mLux = that.getLux();
@@ -117,6 +122,7 @@
         mTime = SystemClock.uptimeMillis();
         mPhysicalDisplayId = "";
         mDisplayState = Display.STATE_UNKNOWN;
+        mDisplayPolicy = POLICY_OFF;
         // Lux values
         mLux = 0;
         mPreThresholdLux = 0;
@@ -155,6 +161,7 @@
                 && mDisplayId == that.mDisplayId
                 && mPhysicalDisplayId.equals(that.mPhysicalDisplayId)
                 && mDisplayState == that.mDisplayState
+                && mDisplayPolicy == that.mDisplayPolicy
                 && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux)
                 && Float.floatToRawIntBits(mPreThresholdLux)
                 == Float.floatToRawIntBits(that.mPreThresholdLux)
@@ -191,6 +198,7 @@
                 + "disp=" + mDisplayId
                 + ", physDisp=" + mPhysicalDisplayId
                 + ", displayState=" + Display.stateToString(mDisplayState)
+                + ", displayPolicy=" + policyToString(mDisplayPolicy)
                 + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
                 + ", initBrt=" + mInitialBrightness
                 + ", rcmdBrt=" + mRecommendedBrightness
@@ -251,6 +259,10 @@
         mDisplayState = state;
     }
 
+    public void setDisplayPolicy(int policy) {
+        mDisplayPolicy = policy;
+    }
+
     public float getLux() {
         return mLux;
     }
diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
index a597edd..8fdc22b 100644
--- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
@@ -59,7 +59,7 @@
     private static final String EXTRA_LOCATION_TAGS = "android:location_allow_listed_tags";
     private static final String LOCATION_TAGS_SEPARATOR = ";";
 
-    private static final long RESET_DELAY_MS = 1000;
+    private static final long RESET_DELAY_MS = 10000;
 
     /**
      * Creates and registers this proxy. If no suitable service is available for the proxy, returns
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a3ec3c5..29ea071 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1870,9 +1870,10 @@
         }
     }
 
-    private void onPostPasswordChanged(LockscreenCredential newCredential, int userHandle) {
-        updatePasswordHistory(newCredential, userHandle);
-        mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userHandle);
+    private void onPostPasswordChanged(LockscreenCredential newCredential, int userId) {
+        updatePasswordHistory(newCredential, userId);
+        mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userId);
+        sendMainUserCredentialChangedNotificationIfNeeded(userId);
     }
 
     /**
@@ -3056,7 +3057,6 @@
         setCurrentLskfBasedProtectorId(newProtectorId, userId);
         LockPatternUtils.invalidateCredentialTypeCache();
         synchronizeUnifiedChallengeForProfiles(userId, profilePasswords);
-        sendMainUserCredentialChangedNotificationIfNeeded(userId);
 
         setUserPasswordMetrics(credential, userId);
         mUnifiedProfilePasswordCache.removePassword(userId);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9e98a58..09c6dc0e6 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -128,6 +128,22 @@
      */
     private static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver";
 
+    /**
+     * Action reported to UsageStatsManager when a media session becomes active and user engaged
+     * for a given app. App is expected to show an ongoing notification after this.
+     */
+    private static final String USAGE_STATS_ACTION_START = "start";
+
+    /**
+     * Action reported to UsageStatsManager when a media session is no longer active and user
+     * engaged for a given app. If media session only pauses for a brief time the event will not
+     * necessarily be reported in case user is still "engaging" and will restart it momentarily.
+     * In such case, action may be reported after a short delay to ensure user is truly no longer
+     * engaging. Afterwards, the app is no longer expected to show an ongoing notification.
+     */
+    private static final String USAGE_STATS_ACTION_STOP = "stop";
+    private static final String USAGE_STATS_CATEGORY = "android.media";
+
     private final Context mContext;
     private final SessionManagerImpl mSessionManagerImpl;
     private final MessageHandler mHandler = new MessageHandler();
@@ -639,13 +655,15 @@
         if (userEngaged) {
             if (!mUserEngagingSessions.contains(sessionUid)) {
                 mUserEngagingSessions.put(sessionUid, new HashSet<>());
-                reportUserInteractionEvent(/* action= */ "start", record.getUserId(), packageName);
+                reportUserInteractionEvent(
+                    USAGE_STATS_ACTION_START, record.getUserId(), packageName);
             }
             mUserEngagingSessions.get(sessionUid).add(token);
         } else if (mUserEngagingSessions.contains(sessionUid)) {
             mUserEngagingSessions.get(sessionUid).remove(token);
             if (mUserEngagingSessions.get(sessionUid).isEmpty()) {
-                reportUserInteractionEvent(/* action= */ "stop", record.getUserId(), packageName);
+                reportUserInteractionEvent(
+                    USAGE_STATS_ACTION_STOP, record.getUserId(), packageName);
                 mUserEngagingSessions.remove(sessionUid);
             }
         }
@@ -653,7 +671,7 @@
 
     private void reportUserInteractionEvent(String action, int userId, String packageName) {
         PersistableBundle extras = new PersistableBundle();
-        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media");
+        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, USAGE_STATS_CATEGORY);
         extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, action);
         mUsageStatsManagerInternal.reportUserInteractionEvent(packageName, userId, extras);
     }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index a600eea..c1ab3f9 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -520,7 +520,7 @@
         mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
         mShortcutDumpFiles = new ShortcutDumpFiles(this);
         mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, true)
+                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, false)
                 && !injectIsLowRamDevice();
 
         if (onlyForPackageManagerApis) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 428fca0..e9a7fe1 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6410,7 +6410,7 @@
 
     private boolean performHapticFeedback(int effectId, boolean always, String reason) {
         return performHapticFeedback(Process.myUid(), mContext.getOpPackageName(),
-            effectId, always, reason);
+            effectId, always, reason, false /* fromIme */);
     }
 
     @Override
@@ -6420,7 +6420,7 @@
 
     @Override
     public boolean performHapticFeedback(int uid, String packageName, int effectId,
-            boolean always, String reason) {
+            boolean always, String reason, boolean fromIme) {
         if (!mVibrator.hasVibrator()) {
             return false;
         }
@@ -6431,7 +6431,7 @@
         }
         VibrationAttributes attrs =
                 mHapticFeedbackVibrationProvider.getVibrationAttributesForHapticFeedback(
-                        effectId, /* bypassVibrationIntensitySetting= */ always);
+                        effectId, /* bypassVibrationIntensitySetting= */ always, fromIme);
         VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, effectId);
         mVibrator.vibrate(uid, packageName, effect, reason, attrs);
         return true;
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 2174fd6..5956594 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1072,7 +1072,7 @@
      * Call from application to perform haptic feedback on its window.
      */
     public boolean performHapticFeedback(int uid, String packageName, int effectId,
-            boolean always, String reason);
+            boolean always, String reason, boolean fromIme);
 
     /**
      * Called when we have started keeping the screen on because a window
diff --git a/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java b/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java
new file mode 100644
index 0000000..7ee2901
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.vibrator;
+
+import android.os.SystemClock;
+import android.util.IndentingPrintWriter;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import java.util.ArrayDeque;
+
+/**
+ * A generic grouped list of aggregated log records to be printed in dumpsys.
+ *
+ * <p>This can be used to dump history of operations or requests to the vibrator services, e.g.
+ * vibration requests grouped by usage or vibration parameters sent to the vibrator control service.
+ *
+ * @param <T> The type of log entries aggregated in this record.
+ */
+abstract class GroupedAggregatedLogRecords<T extends GroupedAggregatedLogRecords.SingleLogRecord> {
+    private final SparseArray<ArrayDeque<AggregatedLogRecord<T>>> mGroupedRecords;
+    private final int mSizeLimit;
+    private final int mAggregationTimeLimitMs;
+
+    GroupedAggregatedLogRecords(int sizeLimit, int aggregationTimeLimitMs) {
+        mGroupedRecords = new SparseArray<>();
+        mSizeLimit = sizeLimit;
+        mAggregationTimeLimitMs = aggregationTimeLimitMs;
+    }
+
+    /** Prints a header to identify the group to be logged. */
+    abstract void dumpGroupHeader(IndentingPrintWriter pw, int groupKey);
+
+    /** Returns the {@link ProtoOutputStream} repeated field id to log records of this group. */
+    abstract long findGroupKeyProtoFieldId(int groupKey);
+
+    /**
+     * Adds given entry to this record list, dropping the oldest record if size limit was reached
+     * for its group.
+     *
+     * @param record The new {@link SingleLogRecord} to be recorded.
+     * @return The oldest {@link AggregatedLogRecord} entry being dropped from the group list if
+     * it's full, null otherwise.
+     */
+    final synchronized AggregatedLogRecord<T> add(T record) {
+        int groupKey = record.getGroupKey();
+        if (!mGroupedRecords.contains(groupKey)) {
+            mGroupedRecords.put(groupKey, new ArrayDeque<>(mSizeLimit));
+        }
+        ArrayDeque<AggregatedLogRecord<T>> records = mGroupedRecords.get(groupKey);
+        if (mAggregationTimeLimitMs > 0 && !records.isEmpty()) {
+            AggregatedLogRecord<T> lastAggregatedRecord = records.getLast();
+            if (lastAggregatedRecord.mayAggregate(record, mAggregationTimeLimitMs)) {
+                lastAggregatedRecord.record(record);
+                return null;
+            }
+        }
+        AggregatedLogRecord<T> removedRecord = null;
+        if (records.size() >= mSizeLimit) {
+            removedRecord = records.removeFirst();
+        }
+        records.addLast(new AggregatedLogRecord<>(record));
+        return removedRecord;
+    }
+
+    final synchronized void dump(IndentingPrintWriter pw) {
+        for (int i = 0; i < mGroupedRecords.size(); i++) {
+            dumpGroupHeader(pw, mGroupedRecords.keyAt(i));
+            pw.increaseIndent();
+            for (AggregatedLogRecord<T> records : mGroupedRecords.valueAt(i)) {
+                records.dump(pw);
+            }
+            pw.decreaseIndent();
+            pw.println();
+        }
+    }
+
+    final synchronized void dump(ProtoOutputStream proto) {
+        for (int i = 0; i < mGroupedRecords.size(); i++) {
+            long fieldId = findGroupKeyProtoFieldId(mGroupedRecords.keyAt(i));
+            for (AggregatedLogRecord<T> records : mGroupedRecords.valueAt(i)) {
+                records.dump(proto, fieldId);
+            }
+        }
+    }
+
+    /**
+     * Represents an aggregation of log record entries that can be printed in a compact manner.
+     *
+     * <p>The aggregation is controlled by a time limit on the difference between the creation time
+     * of two consecutive entries that {@link SingleLogRecord#mayAggregate}.
+     *
+     * @param <T> The type of log entries aggregated in this record.
+     */
+    static final class AggregatedLogRecord<T extends SingleLogRecord> {
+        private final T mFirst;
+        private T mLatest;
+        private int mCount;
+
+        AggregatedLogRecord(T record) {
+            mLatest = mFirst = record;
+            mCount = 1;
+        }
+
+        T getLatest() {
+            return mLatest;
+        }
+
+        synchronized boolean mayAggregate(T record, long timeLimitMs) {
+            long timeDeltaMs = Math.abs(mLatest.getCreateUptimeMs() - record.getCreateUptimeMs());
+            return mLatest.mayAggregate(record) && timeDeltaMs < timeLimitMs;
+        }
+
+        synchronized void record(T record) {
+            mLatest = record;
+            mCount++;
+        }
+
+        synchronized void dump(IndentingPrintWriter pw) {
+            mFirst.dump(pw);
+            if (mCount == 1) {
+                return;
+            }
+            if (mCount > 2) {
+                pw.println("-> Skipping " + (mCount - 2) + " aggregated entries, latest:");
+            }
+            mLatest.dump(pw);
+        }
+
+        synchronized void dump(ProtoOutputStream proto, long fieldId) {
+            mFirst.dump(proto, fieldId);
+            if (mCount > 1) {
+                mLatest.dump(proto, fieldId);
+            }
+        }
+    }
+
+    /**
+     * Represents a single log entry that can be grouped and aggregated for compact logging.
+     *
+     * <p>Entries are first grouped by an integer group key, and then aggregated with consecutive
+     * entries of same group within a limited timespan.
+     */
+    interface SingleLogRecord {
+
+        /** The group identifier for this record (e.g. vibration usage). */
+        int getGroupKey();
+
+        /**
+         * The timestamp in millis that should be used for aggregation of close entries.
+         *
+         * <p>Should be {@link SystemClock#uptimeMillis()} to be used for calculations.
+         */
+        long getCreateUptimeMs();
+
+        /**
+         * Returns true if this record can be aggregated with the given one (e.g. the represent the
+         * same vibration request from the same process client).
+         */
+        boolean mayAggregate(SingleLogRecord record);
+
+        /** Writes this record into given {@link IndentingPrintWriter}. */
+        void dump(IndentingPrintWriter pw);
+
+        /** Writes this record into given {@link ProtoOutputStream} field. */
+        void dump(ProtoOutputStream proto, long fieldId);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/HalVibration.java b/services/core/java/com/android/server/vibrator/HalVibration.java
index 70e2e27..8f755f4 100644
--- a/services/core/java/com/android/server/vibrator/HalVibration.java
+++ b/services/core/java/com/android/server/vibrator/HalVibration.java
@@ -54,12 +54,18 @@
     /** Vibration status. */
     private Vibration.Status mStatus;
 
+    /** Reported scale values applied to the vibration effects. */
+    private int mScaleLevel;
+    private float mAdaptiveScale;
+
     HalVibration(@NonNull IBinder token, @NonNull CombinedVibration effect,
             @NonNull CallerInfo callerInfo) {
         super(token, callerInfo);
         mOriginalEffect = effect;
         mEffectToPlay = effect;
         mStatus = Vibration.Status.RUNNING;
+        mScaleLevel = VibrationScaler.SCALE_NONE;
+        mAdaptiveScale = VibrationScaler.ADAPTIVE_SCALE_NONE;
     }
 
     /**
@@ -119,20 +125,24 @@
     }
 
     /**
-     * Scales the {@link #getEffectToPlay()} and each fallback effect with a scaling transformation.
-     *
-     * @param scaler A {@link VibrationEffect.Transformation<Integer>} that takes one of the
-     *               {@code VibrationAttributes.USAGE_*} as the modifier to scale the effect
-     *               based on the user settings.
+     * Scales the {@link #getEffectToPlay()} and each fallback effect based on the vibration usage.
      */
-    public void scaleEffects(VibrationEffect.Transformation<Integer> scaler) {
+    public void scaleEffects(VibrationScaler scaler) {
         int vibrationUsage = callerInfo.attrs.getUsage();
-        CombinedVibration newEffect = mEffectToPlay.transform(scaler, vibrationUsage);
+
+        // Save scale values for debugging purposes.
+        mScaleLevel = scaler.getScaleLevel(vibrationUsage);
+        mAdaptiveScale = scaler.getAdaptiveHapticsScale(vibrationUsage);
+
+        // Scale all VibrationEffect instances in given CombinedVibration.
+        CombinedVibration newEffect = mEffectToPlay.transform(scaler::scale, vibrationUsage);
         if (!Objects.equals(mEffectToPlay, newEffect)) {
             mEffectToPlay = newEffect;
         }
+
+        // Scale all fallback VibrationEffect instances that can be used by VibrationThread.
         for (int i = 0; i < mFallbacks.size(); i++) {
-            mFallbacks.setValueAt(i, scaler.transform(mFallbacks.valueAt(i), vibrationUsage));
+            mFallbacks.setValueAt(i, scaler.scale(mFallbacks.valueAt(i), vibrationUsage));
         }
     }
 
@@ -171,7 +181,7 @@
         CombinedVibration originalEffect =
                 Objects.equals(mOriginalEffect, mEffectToPlay) ? null : mOriginalEffect;
         return new Vibration.DebugInfo(mStatus, stats, mEffectToPlay, originalEffect,
-                /* scale= */ 0, callerInfo);
+                mScaleLevel, mAdaptiveScale, callerInfo);
     }
 
     /** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
index a346216..9756094 100644
--- a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
+++ b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
@@ -19,8 +19,8 @@
 import android.annotation.Nullable;
 import android.content.res.Resources;
 import android.os.VibrationEffect;
-import android.os.vibrator.Flags;
 import android.os.VibratorInfo;
+import android.os.vibrator.Flags;
 import android.os.vibrator.persistence.ParsedVibration;
 import android.os.vibrator.persistence.VibrationXmlParser;
 import android.text.TextUtils;
@@ -73,8 +73,6 @@
  *
  * <p>After a successful parsing of the customization XML file, it returns a {@link SparseArray}
  * that maps each customized haptic feedback effect ID to its respective {@link VibrationEffect}.
- *
- * @hide
  */
 final class HapticFeedbackCustomization {
     private static final String TAG = "HapticFeedbackCustomization";
@@ -104,8 +102,6 @@
      * @throws {@link IOException} if an IO error occurs while parsing the customization XML.
      * @throws {@link CustomizationParserException} for any non-IO error that occurs when parsing
      *      the XML, like an invalid XML content or an invalid haptic feedback constant.
-     *
-     * @hide
      */
     @Nullable
     static SparseArray<VibrationEffect> loadVibrations(Resources res, VibratorInfo vibratorInfo)
@@ -202,8 +198,6 @@
 
     /**
      * Represents an error while parsing a haptic feedback customization XML.
-     *
-     * @hide
      */
     static final class CustomizationParserException extends Exception {
         private CustomizationParserException(String message) {
diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
index 519acec..96f045d 100644
--- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
+++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
@@ -34,8 +34,6 @@
 
 /**
  * Provides the {@link VibrationEffect} and {@link VibrationAttributes} for haptic feedback.
- *
- * @hide
  */
 public final class HapticFeedbackVibrationProvider {
     private static final String TAG = "HapticFeedbackVibrationProvider";
@@ -58,17 +56,14 @@
 
     private float mKeyboardVibrationFixedAmplitude;
 
-    /** @hide */
     public HapticFeedbackVibrationProvider(Resources res, Vibrator vibrator) {
         this(res, vibrator.getInfo());
     }
 
-    /** @hide */
     public HapticFeedbackVibrationProvider(Resources res, VibratorInfo vibratorInfo) {
         this(res, vibratorInfo, loadHapticCustomizations(res, vibratorInfo));
     }
 
-    /** @hide */
     @VisibleForTesting HapticFeedbackVibrationProvider(
             Resources res,
             VibratorInfo vibratorInfo,
@@ -190,10 +185,11 @@
      *      to get.
      * @param bypassVibrationIntensitySetting {@code true} if the returned attribute should bypass
      *      vibration intensity settings. {@code false} otherwise.
+     * @param fromIme the haptic feedback is performed from an IME.
      * @return the {@link VibrationAttributes} that should be used for the provided haptic feedback.
      */
     public VibrationAttributes getVibrationAttributesForHapticFeedback(
-            int effectId, boolean bypassVibrationIntensitySetting) {
+            int effectId, boolean bypassVibrationIntensitySetting, boolean fromIme) {
         VibrationAttributes attrs;
         switch (effectId) {
             case HapticFeedbackConstants.EDGE_SQUEEZE:
@@ -209,7 +205,7 @@
                 break;
             case HapticFeedbackConstants.KEYBOARD_TAP:
             case HapticFeedbackConstants.KEYBOARD_RELEASE:
-                attrs = createKeyboardVibrationAttributes();
+                attrs = createKeyboardVibrationAttributes(fromIme);
                 break;
             default:
                 attrs = TOUCH_VIBRATION_ATTRIBUTES;
@@ -222,7 +218,7 @@
         if (shouldBypassInterruptionPolicy(effectId)) {
             flags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
         }
-        if (shouldBypassIntensityScale(effectId)) {
+        if (shouldBypassIntensityScale(effectId, fromIme)) {
             flags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE;
         }
 
@@ -337,9 +333,9 @@
                 /* fallbackForPredefinedEffect= */ predefinedEffectFallback);
     }
 
-    private boolean shouldBypassIntensityScale(int effectId) {
-        if (!Flags.keyboardCategoryEnabled() || mKeyboardVibrationFixedAmplitude < 0) {
-            // shouldn't bypass if not support keyboard category or no fixed amplitude
+    private boolean shouldBypassIntensityScale(int effectId, boolean isIme) {
+        if (!Flags.keyboardCategoryEnabled() || mKeyboardVibrationFixedAmplitude < 0 || !isIme) {
+            // Shouldn't bypass if not support keyboard category, no fixed amplitude or not an IME.
             return false;
         }
         switch (effectId) {
@@ -353,8 +349,9 @@
         return false;
     }
 
-    private static VibrationAttributes createKeyboardVibrationAttributes() {
-        if (!Flags.keyboardCategoryEnabled()) {
+    private VibrationAttributes createKeyboardVibrationAttributes(boolean fromIme) {
+        // Use touch attribute when the keyboard category is disable or it's not from an IME.
+        if (!Flags.keyboardCategoryEnabled() || !fromIme) {
             return TOUCH_VIBRATION_ATTRIBUTES;
         }
 
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index b2e808a..b490f57 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -218,12 +218,13 @@
         private final long mDurationMs;
         @Nullable
         private final CombinedVibration mOriginalEffect;
-        private final float mScale;
+        private final int mScaleLevel;
+        private final float mAdaptiveScale;
         private final Status mStatus;
 
         DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration playedEffect,
-                @Nullable CombinedVibration originalEffect, float scale,
-                @NonNull CallerInfo callerInfo) {
+                @Nullable CombinedVibration originalEffect, int scaleLevel,
+                float adaptiveScale, @NonNull CallerInfo callerInfo) {
             Objects.requireNonNull(callerInfo);
             mCreateTime = stats.getCreateTimeDebug();
             mStartTime = stats.getStartTimeDebug();
@@ -231,7 +232,8 @@
             mDurationMs = stats.getDurationDebug();
             mPlayedEffect = playedEffect;
             mOriginalEffect = originalEffect;
-            mScale = scale;
+            mScaleLevel = scaleLevel;
+            mAdaptiveScale = adaptiveScale;
             mCallerInfo = callerInfo;
             mStatus = status;
         }
@@ -246,7 +248,8 @@
                     + ", status: " + mStatus.name().toLowerCase(Locale.ROOT)
                     + ", playedEffect: " + mPlayedEffect
                     + ", originalEffect: " + mOriginalEffect
-                    + ", scale: " + String.format(Locale.ROOT, "%.2f", mScale)
+                    + ", scaleLevel: " + VibrationScaler.scaleLevelToString(mScaleLevel)
+                    + ", adaptiveScale: " + String.format(Locale.ROOT, "%.2f", mAdaptiveScale)
                     + ", callerInfo: " + mCallerInfo;
         }
 
@@ -259,26 +262,39 @@
         void dumpCompact(IndentingPrintWriter pw) {
             boolean isExternalVibration = mPlayedEffect == null;
             String timingsStr = String.format(Locale.ROOT,
-                    "%s | %8s | %20s | duration: %5dms | start: %12s | end: %10s",
+                    "%s | %8s | %20s | duration: %5dms | start: %12s | end: %12s",
                     DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)),
                     isExternalVibration ? "external" : "effect",
                     mStatus.name().toLowerCase(Locale.ROOT),
                     mDurationMs,
                     mStartTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mStartTime)),
                     mEndTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mEndTime)));
-            String callerInfoStr = String.format(Locale.ROOT,
-                    " | %s (uid=%d, deviceId=%d) | usage: %s (audio=%s) | flags: %s | reason: %s",
-                    mCallerInfo.opPkg, mCallerInfo.uid, mCallerInfo.deviceId,
-                    mCallerInfo.attrs.usageToString(),
-                    AudioAttributes.usageToString(mCallerInfo.attrs.getAudioUsage()),
+            String paramStr = String.format(Locale.ROOT,
+                    " | scale: %8s (adaptive=%.2f) | flags: %4s | usage: %s",
+                    VibrationScaler.scaleLevelToString(mScaleLevel), mAdaptiveScale,
                     Long.toBinaryString(mCallerInfo.attrs.getFlags()),
-                    mCallerInfo.reason);
+                    mCallerInfo.attrs.usageToString());
+            // Optional, most vibrations have category unknown so skip them to simplify the logs
+            String categoryStr =
+                    mCallerInfo.attrs.getCategory() != VibrationAttributes.CATEGORY_UNKNOWN
+                            ? " | category=" + VibrationAttributes.categoryToString(
+                            mCallerInfo.attrs.getCategory())
+                            : "";
+            // Optional, most vibrations should not be defined via AudioAttributes
+            // so skip them to simplify the logs
+            String audioUsageStr =
+                    mCallerInfo.attrs.getOriginalAudioUsage() != AudioAttributes.USAGE_UNKNOWN
+                            ? " | audioUsage=" + AudioAttributes.usageToString(
+                            mCallerInfo.attrs.getOriginalAudioUsage())
+                            : "";
+            String callerStr = String.format(Locale.ROOT,
+                    " | %s (uid=%d, deviceId=%d) | reason: %s",
+                    mCallerInfo.opPkg, mCallerInfo.uid, mCallerInfo.deviceId, mCallerInfo.reason);
             String effectStr = String.format(Locale.ROOT,
-                    " | played: %s | original: %s | scale: %.2f",
+                    " | played: %s | original: %s",
                     mPlayedEffect == null ? null : mPlayedEffect.toDebugString(),
-                    mOriginalEffect == null ? null : mOriginalEffect.toDebugString(),
-                    mScale);
-            pw.println(timingsStr + callerInfoStr + effectStr);
+                    mOriginalEffect == null ? null : mOriginalEffect.toDebugString());
+            pw.println(timingsStr + paramStr + categoryStr + audioUsageStr + callerStr + effectStr);
         }
 
         /** Write this info into given {@link PrintWriter}. */
@@ -293,7 +309,8 @@
                     + (mEndTime == 0 ? null : DEBUG_DATE_TIME_FORMAT.format(new Date(mEndTime))));
             pw.println("playedEffect = " + mPlayedEffect);
             pw.println("originalEffect = " + mOriginalEffect);
-            pw.println("scale = " + String.format(Locale.ROOT, "%.2f", mScale));
+            pw.println("scale = " + VibrationScaler.scaleLevelToString(mScaleLevel));
+            pw.println("adaptiveScale = " + String.format(Locale.ROOT, "%.2f", mAdaptiveScale));
             pw.println("callerInfo = " + mCallerInfo);
             pw.decreaseIndent();
         }
@@ -310,6 +327,7 @@
             final VibrationAttributes attrs = mCallerInfo.attrs;
             proto.write(VibrationAttributesProto.USAGE, attrs.getUsage());
             proto.write(VibrationAttributesProto.AUDIO_USAGE, attrs.getAudioUsage());
+            proto.write(VibrationAttributesProto.CATEGORY, attrs.getCategory());
             proto.write(VibrationAttributesProto.FLAGS, attrs.getFlags());
             proto.end(attrsToken);
 
diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java
index 5d17884..d9ca710 100644
--- a/services/core/java/com/android/server/vibrator/VibrationScaler.java
+++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java
@@ -26,10 +26,14 @@
 import android.os.vibrator.Flags;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.VibrationEffectSegment;
+import android.util.IndentingPrintWriter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Locale;
 
 /** Controls vibration scaling. */
 final class VibrationScaler {
@@ -37,13 +41,12 @@
 
     // Scale levels. Each level, except MUTE, is defined as the delta between the current setting
     // and the default intensity for that type of vibration (i.e. current - default).
-    private static final int SCALE_VERY_LOW =
-            ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW; // -2
-    private static final int SCALE_LOW = ExternalVibrationScale.ScaleLevel.SCALE_LOW; // -1
-    private static final int SCALE_NONE = ExternalVibrationScale.ScaleLevel.SCALE_NONE; // 0
-    private static final int SCALE_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_HIGH; // 1
-    private static final int SCALE_VERY_HIGH =
-            ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH; // 2
+    static final int SCALE_VERY_LOW = ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW; // -2
+    static final int SCALE_LOW = ExternalVibrationScale.ScaleLevel.SCALE_LOW; // -1
+    static final int SCALE_NONE = ExternalVibrationScale.ScaleLevel.SCALE_NONE; // 0
+    static final int SCALE_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_HIGH; // 1
+    static final int SCALE_VERY_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH; // 2
+    static final float ADAPTIVE_SCALE_NONE = 1f;
 
     // Scale factors for each level.
     private static final float SCALE_FACTOR_VERY_LOW = 0.6f;
@@ -52,6 +55,8 @@
     private static final float SCALE_FACTOR_HIGH = 1.2f;
     private static final float SCALE_FACTOR_VERY_HIGH = 1.4f;
 
+    private static final ScaleLevel SCALE_LEVEL_NONE = new ScaleLevel(SCALE_FACTOR_NONE);
+
     // A mapping from the intensity adjustment to the scaling to apply, where the intensity
     // adjustment is defined as the delta between the default intensity level and the user selected
     // intensity level. It's important that we apply the scaling on the delta between the two so
@@ -69,7 +74,7 @@
         mScaleLevels = new SparseArray<>();
         mScaleLevels.put(SCALE_VERY_LOW, new ScaleLevel(SCALE_FACTOR_VERY_LOW));
         mScaleLevels.put(SCALE_LOW, new ScaleLevel(SCALE_FACTOR_LOW));
-        mScaleLevels.put(SCALE_NONE, new ScaleLevel(SCALE_FACTOR_NONE));
+        mScaleLevels.put(SCALE_NONE, SCALE_LEVEL_NONE);
         mScaleLevels.put(SCALE_HIGH, new ScaleLevel(SCALE_FACTOR_HIGH));
         mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_FACTOR_VERY_HIGH));
     }
@@ -87,25 +92,24 @@
      * @param usageHint one of VibrationAttributes.USAGE_*
      * @return one of ExternalVibrationScale.ScaleLevel.SCALE_*
      */
-    public int getExternalVibrationScaleLevel(int usageHint) {
+    public int getScaleLevel(int usageHint) {
         int defaultIntensity = mSettingsController.getDefaultIntensity(usageHint);
         int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
-
         if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) {
             // Bypassing user settings, or it has changed between checking and scaling. Use default.
             return SCALE_NONE;
         }
 
         int scaleLevel = currentIntensity - defaultIntensity;
-
         if (scaleLevel >= SCALE_VERY_LOW && scaleLevel <= SCALE_VERY_HIGH) {
             return scaleLevel;
-        } else {
-            // Something about our scaling has gone wrong, so just play with no scaling.
-            Slog.w(TAG, "Error in scaling calculations, ended up with invalid scale level "
-                    + scaleLevel + " for vibration with usage " + usageHint);
-            return SCALE_NONE;
         }
+
+        // Something about our scaling has gone wrong, so just play with no scaling.
+        Slog.wtf(TAG, "Error in scaling calculations, ended up with invalid scale level "
+                + scaleLevel + " for vibration with usage " + usageHint);
+
+        return SCALE_NONE;
     }
 
     /**
@@ -117,11 +121,9 @@
      * @return The adaptive haptics scale.
      */
     public float getAdaptiveHapticsScale(int usageHint) {
-        if (shouldApplyAdaptiveHapticsScale(usageHint)) {
-            return mAdaptiveHapticsScales.get(usageHint);
-        }
-
-        return 1f; // no scaling
+        return Flags.adaptiveHapticsEnabled()
+                ? mAdaptiveHapticsScales.get(usageHint, ADAPTIVE_SCALE_NONE)
+                : ADAPTIVE_SCALE_NONE;
     }
 
     /**
@@ -140,21 +142,16 @@
             return effect;
         }
 
-        int defaultIntensity = mSettingsController.getDefaultIntensity(usageHint);
-        int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
-
-        if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) {
-            // Bypassing user settings, or it has changed between checking and scaling. Use default.
-            currentIntensity = defaultIntensity;
-        }
-
-        int newEffectStrength = intensityToEffectStrength(currentIntensity);
-        ScaleLevel scaleLevel = mScaleLevels.get(currentIntensity - defaultIntensity);
+        int newEffectStrength = getEffectStrength(usageHint);
+        ScaleLevel scaleLevel = mScaleLevels.get(getScaleLevel(usageHint));
+        float adaptiveScale = getAdaptiveHapticsScale(usageHint);
 
         if (scaleLevel == null) {
             // Something about our scaling has gone wrong, so just play with no scaling.
-            Slog.e(TAG, "No configured scaling level!"
-                    + " (current=" + currentIntensity + ", default= " + defaultIntensity + ")");
+            Slog.e(TAG, "No configured scaling level found! (current="
+                    + mSettingsController.getCurrentIntensity(usageHint) + ", default= "
+                    + mSettingsController.getDefaultIntensity(usageHint) + ")");
+            scaleLevel = SCALE_LEVEL_NONE;
         }
 
         VibrationEffect.Composed composedEffect = (VibrationEffect.Composed) effect;
@@ -162,20 +159,11 @@
                 new ArrayList<>(composedEffect.getSegments());
         int segmentCount = segments.size();
         for (int i = 0; i < segmentCount; i++) {
-            VibrationEffectSegment segment = segments.get(i);
-            segment = segment.resolve(mDefaultVibrationAmplitude)
-                    .applyEffectStrength(newEffectStrength);
-            if (scaleLevel != null) {
-                segment = segment.scale(scaleLevel.factor);
-            }
-
-            // If adaptive haptics scaling is available for this usage, apply it to the segment.
-            if (shouldApplyAdaptiveHapticsScale(usageHint)) {
-                float adaptiveScale = mAdaptiveHapticsScales.get(usageHint);
-                segment = segment.scaleLinearly(adaptiveScale);
-            }
-
-            segments.set(i, segment);
+            segments.set(i,
+                    segments.get(i).resolve(mDefaultVibrationAmplitude)
+                            .applyEffectStrength(newEffectStrength)
+                            .scale(scaleLevel.factor)
+                            .scaleLinearly(adaptiveScale));
         }
         if (segments.equals(composedEffect.getSegments())) {
             // No segment was updated, return original effect.
@@ -197,15 +185,7 @@
      * updated effect strength
      */
     public PrebakedSegment scale(PrebakedSegment prebaked, int usageHint) {
-        int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
-
-        if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) {
-            // Bypassing user settings, or it has changed between checking and scaling. Use default.
-            currentIntensity = mSettingsController.getDefaultIntensity(usageHint);
-        }
-
-        int newEffectStrength = intensityToEffectStrength(currentIntensity);
-        return prebaked.applyEffectStrength(newEffectStrength);
+        return prebaked.applyEffectStrength(getEffectStrength(usageHint));
     }
 
     /**
@@ -213,8 +193,6 @@
      *
      * @param usageHint one of VibrationAttributes.USAGE_*.
      * @param scale The scaling factor that should be applied to vibrations of this usage.
-     *
-     * @hide
      */
     public void updateAdaptiveHapticsScale(@VibrationAttributes.Usage int usageHint, float scale) {
         mAdaptiveHapticsScales.put(usageHint, scale);
@@ -224,24 +202,68 @@
      * Removes the usage from the cached adaptive haptics scales list.
      *
      * @param usageHint one of VibrationAttributes.USAGE_*.
-     *
-     * @hide
      */
     public void removeAdaptiveHapticsScale(@VibrationAttributes.Usage int usageHint) {
         mAdaptiveHapticsScales.remove(usageHint);
     }
 
-    /**
-     * Removes all cached adaptive haptics scales.
-     *
-     * @hide
-     */
+    /** Removes all cached adaptive haptics scales. */
     public void clearAdaptiveHapticsScales() {
         mAdaptiveHapticsScales.clear();
     }
 
-    private boolean shouldApplyAdaptiveHapticsScale(int usageHint) {
-        return Flags.adaptiveHapticsEnabled() && mAdaptiveHapticsScales.contains(usageHint);
+    /** Write current settings into given {@link PrintWriter}. */
+    void dump(IndentingPrintWriter pw) {
+        pw.println("VibrationScaler:");
+        pw.increaseIndent();
+        pw.println("defaultVibrationAmplitude = " + mDefaultVibrationAmplitude);
+
+        pw.println("ScaleLevels:");
+        pw.increaseIndent();
+        for (int i = 0; i < mScaleLevels.size(); i++) {
+            int scaleLevelKey = mScaleLevels.keyAt(i);
+            ScaleLevel scaleLevel = mScaleLevels.valueAt(i);
+            pw.println(scaleLevelToString(scaleLevelKey) + " = " + scaleLevel);
+        }
+        pw.decreaseIndent();
+
+        pw.println("AdaptiveHapticsScales:");
+        pw.increaseIndent();
+        for (int i = 0; i < mAdaptiveHapticsScales.size(); i++) {
+            int usage = mAdaptiveHapticsScales.keyAt(i);
+            float scale = mAdaptiveHapticsScales.valueAt(i);
+            pw.println(VibrationAttributes.usageToString(usage)
+                    + " = " + String.format(Locale.ROOT, "%.2f", scale));
+        }
+        pw.decreaseIndent();
+
+        pw.decreaseIndent();
+    }
+
+    /** Write current settings into given {@link ProtoOutputStream}. */
+    void dump(ProtoOutputStream proto) {
+        proto.write(VibratorManagerServiceDumpProto.DEFAULT_VIBRATION_AMPLITUDE,
+                mDefaultVibrationAmplitude);
+    }
+
+    @Override
+    public String toString() {
+        return "VibrationScaler{"
+                + "mScaleLevels=" + mScaleLevels
+                + ", mDefaultVibrationAmplitude=" + mDefaultVibrationAmplitude
+                + ", mAdaptiveHapticsScales=" + mAdaptiveHapticsScales
+                + '}';
+    }
+
+    private int getEffectStrength(int usageHint) {
+        int currentIntensity = mSettingsController.getCurrentIntensity(usageHint);
+
+        if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) {
+            // Bypassing user settings, or it has changed between checking and scaling. Use default.
+            currentIntensity = mSettingsController.getDefaultIntensity(usageHint);
+        }
+
+        return intensityToEffectStrength(currentIntensity);
     }
 
     /** Mapping of Vibrator.VIBRATION_INTENSITY_* values to {@link EffectStrength}. */
@@ -259,6 +281,17 @@
         }
     }
 
+    static String scaleLevelToString(int scaleLevel) {
+        return switch (scaleLevel) {
+            case SCALE_VERY_LOW -> "VERY_LOW";
+            case SCALE_LOW -> "LOW";
+            case SCALE_NONE -> "NONE";
+            case SCALE_HIGH -> "HIGH";
+            case SCALE_VERY_HIGH -> "VERY_HIGH";
+            default -> String.valueOf(scaleLevel);
+        };
+    }
+
     /** Represents the scale that must be applied to a vibration effect intensity. */
     private static final class ScaleLevel {
         public final float factor;
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 99ce3e2..5b77433 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -386,7 +386,6 @@
      * Returns the duration, in milliseconds, that the vibrator control service will wait for new
      * vibration params.
      * @return The request vibration params timeout in milliseconds.
-     * @hide
      */
     public int getRequestVibrationParamsTimeoutMs() {
         return mVibrationConfig.getRequestVibrationParamsTimeoutMs();
@@ -645,11 +644,16 @@
                         .append("), ");
             }
             vibrationIntensitiesString.append('}');
+            String keyboardVibrationOnString = mKeyboardVibrationOn
+                    + " (default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled() + ")";
             return "VibrationSettings{"
                     + "mVibratorConfig=" + mVibrationConfig
+                    + ", mVibrateOn=" + mVibrateOn
+                    + ", mKeyboardVibrationOn=" + keyboardVibrationOnString
                     + ", mVibrateInputDevices=" + mVibrateInputDevices
                     + ", mBatterySaverMode=" + mBatterySaverMode
-                    + ", mVibrateOn=" + mVibrateOn
+                    + ", mRingerMode=" + ringerModeToString(mRingerMode)
+                    + ", mOnWirelessCharger=" + mOnWirelessCharger
                     + ", mVibrationIntensities=" + vibrationIntensitiesString
                     + ", mProcStatesCache=" + mUidObserver.mProcStatesCache
                     + '}';
@@ -658,32 +662,40 @@
 
     /** Write current settings into given {@link PrintWriter}. */
     void dump(IndentingPrintWriter pw) {
-        pw.println("VibrationSettings:");
-        pw.increaseIndent();
-        pw.println("vibrateOn = " + mVibrateOn);
-        pw.println("vibrateInputDevices = " + mVibrateInputDevices);
-        pw.println("batterySaverMode = " + mBatterySaverMode);
-        pw.println("VibrationIntensities:");
+        synchronized (mLock) {
+            pw.println("VibrationSettings:");
+            pw.increaseIndent();
+            pw.println("vibrateOn = " + mVibrateOn);
+            pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn
+                    + ", default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled());
+            pw.println("vibrateInputDevices = " + mVibrateInputDevices);
+            pw.println("batterySaverMode = " + mBatterySaverMode);
+            pw.println("ringerMode = " + ringerModeToString(mRingerMode));
+            pw.println("onWirelessCharger = " + mOnWirelessCharger);
+            pw.println("processStateCache size = " + mUidObserver.mProcStatesCache.size());
 
-        pw.increaseIndent();
-        for (int i = 0; i < mCurrentVibrationIntensities.size(); i++) {
-            int usage = mCurrentVibrationIntensities.keyAt(i);
-            int intensity = mCurrentVibrationIntensities.valueAt(i);
-            pw.println(VibrationAttributes.usageToString(usage) + " = "
-                    + intensityToString(intensity)
-                    + ", default: " + intensityToString(getDefaultIntensity(usage)));
+            pw.println("VibrationIntensities:");
+            pw.increaseIndent();
+            for (int i = 0; i < mCurrentVibrationIntensities.size(); i++) {
+                int usage = mCurrentVibrationIntensities.keyAt(i);
+                int intensity = mCurrentVibrationIntensities.valueAt(i);
+                pw.println(VibrationAttributes.usageToString(usage) + " = "
+                        + intensityToString(intensity)
+                        + ", default: " + intensityToString(getDefaultIntensity(usage)));
+            }
+            pw.decreaseIndent();
+
+            mVibrationConfig.dumpWithoutDefaultSettings(pw);
+            pw.decreaseIndent();
         }
-        pw.decreaseIndent();
-
-        mVibrationConfig.dumpWithoutDefaultSettings(pw);
-        pw.println("processStateCache = " + mUidObserver.mProcStatesCache);
-        pw.decreaseIndent();
     }
 
     /** Write current settings into given {@link ProtoOutputStream}. */
     void dump(ProtoOutputStream proto) {
         synchronized (mLock) {
             proto.write(VibratorManagerServiceDumpProto.VIBRATE_ON, mVibrateOn);
+            proto.write(VibratorManagerServiceDumpProto.KEYBOARD_VIBRATION_ON,
+                    mKeyboardVibrationOn);
             proto.write(VibratorManagerServiceDumpProto.LOW_POWER_MODE, mBatterySaverMode);
             proto.write(VibratorManagerServiceDumpProto.ALARM_INTENSITY,
                     getCurrentIntensity(USAGE_ALARM));
@@ -723,18 +735,22 @@
     }
 
     private static String intensityToString(int intensity) {
-        switch (intensity) {
-            case Vibrator.VIBRATION_INTENSITY_OFF:
-                return "OFF";
-            case Vibrator.VIBRATION_INTENSITY_LOW:
-                return "LOW";
-            case Vibrator.VIBRATION_INTENSITY_MEDIUM:
-                return "MEDIUM";
-            case Vibrator.VIBRATION_INTENSITY_HIGH:
-                return "HIGH";
-            default:
-                return "UNKNOWN INTENSITY " + intensity;
-        }
+        return switch (intensity) {
+            case Vibrator.VIBRATION_INTENSITY_OFF -> "OFF";
+            case Vibrator.VIBRATION_INTENSITY_LOW -> "LOW";
+            case Vibrator.VIBRATION_INTENSITY_MEDIUM -> "MEDIUM";
+            case Vibrator.VIBRATION_INTENSITY_HIGH -> "HIGH";
+            default -> "UNKNOWN INTENSITY " + intensity;
+        };
+    }
+
+    private static String ringerModeToString(int ringerMode) {
+        return switch (ringerMode) {
+            case AudioManager.RINGER_MODE_SILENT -> "silent";
+            case AudioManager.RINGER_MODE_VIBRATE -> "vibrate";
+            case AudioManager.RINGER_MODE_NORMAL -> "normal";
+            default -> String.valueOf(ringerMode);
+        };
     }
 
     @VibrationIntensity
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
index f6af9ad..f510b4e 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -161,7 +161,7 @@
                 waitForVibrationParamsIfRequired();
             }
             // Scale resolves the default amplitudes from the effect before scaling them.
-            mVibration.scaleEffects(mVibrationScaler::scale);
+            mVibration.scaleEffects(mVibrationScaler);
         } else {
             mVibration.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude());
         }
diff --git a/services/core/java/com/android/server/vibrator/VibratorControlService.java b/services/core/java/com/android/server/vibrator/VibratorControlService.java
index 17a9e33..ec3d99b 100644
--- a/services/core/java/com/android/server/vibrator/VibratorControlService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorControlService.java
@@ -30,6 +30,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
+import android.content.Context;
 import android.frameworks.vibrator.IVibratorControlService;
 import android.frameworks.vibrator.IVibratorController;
 import android.frameworks.vibrator.ScaleParam;
@@ -37,27 +38,38 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.util.IndentingPrintWriter;
+import android.util.IntArray;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 
 /**
  * Implementation of {@link IVibratorControlService} which allows the registration of
  * {@link IVibratorController} to set and receive vibration params.
- *
- * @hide
  */
-public final class VibratorControlService extends IVibratorControlService.Stub {
+final class VibratorControlService extends IVibratorControlService.Stub {
     private static final String TAG = "VibratorControlService";
     private static final int UNRECOGNIZED_VIBRATION_TYPE = -1;
     private static final int NO_SCALE = -1;
 
+    private static final SimpleDateFormat DEBUG_DATE_TIME_FORMAT =
+            new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+
+    private final VibrationParamsRecords mVibrationParamsRecords;
     private final VibratorControllerHolder mVibratorControllerHolder;
     private final VibrationScaler mVibrationScaler;
     private final Object mLock;
@@ -68,25 +80,32 @@
     @GuardedBy("mLock")
     private IBinder mRequestVibrationParamsToken;
 
-    public VibratorControlService(VibratorControllerHolder vibratorControllerHolder,
-            VibrationScaler vibrationScaler, VibrationSettings vibrationSettings, Object lock) {
+    VibratorControlService(Context context,
+            VibratorControllerHolder vibratorControllerHolder, VibrationScaler vibrationScaler,
+            VibrationSettings vibrationSettings, Object lock) {
         mVibratorControllerHolder = vibratorControllerHolder;
         mVibrationScaler = vibrationScaler;
         mLock = lock;
         mRequestVibrationParamsForUsages = vibrationSettings.getRequestVibrationParamsForUsages();
+
+        int dumpSizeLimit = context.getResources().getInteger(
+                com.android.internal.R.integer.config_previousVibrationsDumpSizeLimit);
+        int dumpAggregationTimeLimit = context.getResources().getInteger(
+                com.android.internal.R.integer
+                        .config_previousVibrationsDumpAggregationTimeMillisLimit);
+        mVibrationParamsRecords =
+                new VibrationParamsRecords(dumpSizeLimit, dumpAggregationTimeLimit);
     }
 
     @Override
-    public void registerVibratorController(IVibratorController controller)
-            throws RemoteException {
+    public void registerVibratorController(IVibratorController controller) {
         synchronized (mLock) {
             mVibratorControllerHolder.setVibratorController(controller);
         }
     }
 
     @Override
-    public void unregisterVibratorController(@NonNull IVibratorController controller)
-            throws RemoteException {
+    public void unregisterVibratorController(@NonNull IVibratorController controller) {
         Objects.requireNonNull(controller);
 
         synchronized (mLock) {
@@ -110,7 +129,7 @@
 
     @Override
     public void setVibrationParams(@SuppressLint("ArrayReturn") VibrationParam[] params,
-            @NonNull IVibratorController token) throws RemoteException {
+            @NonNull IVibratorController token) {
         Objects.requireNonNull(token);
 
         synchronized (mLock) {
@@ -128,12 +147,12 @@
             }
 
             updateAdaptiveHapticsScales(params);
+            recordUpdateVibrationParams(params, /* fromRequest= */ false);
         }
     }
 
     @Override
-    public void clearVibrationParams(int types, @NonNull IVibratorController token)
-            throws RemoteException {
+    public void clearVibrationParams(int types, @NonNull IVibratorController token) {
         Objects.requireNonNull(token);
 
         synchronized (mLock) {
@@ -151,13 +170,13 @@
             }
 
             updateAdaptiveHapticsScales(types, NO_SCALE);
+            recordClearVibrationParams(types);
         }
     }
 
     @Override
     public void onRequestVibrationParamsComplete(
-            @NonNull IBinder requestToken, @SuppressLint("ArrayReturn") VibrationParam[] result)
-            throws RemoteException {
+            @NonNull IBinder requestToken, @SuppressLint("ArrayReturn") VibrationParam[] result) {
         Objects.requireNonNull(requestToken);
 
         synchronized (mLock) {
@@ -177,16 +196,17 @@
 
             updateAdaptiveHapticsScales(result);
             endOngoingRequestVibrationParamsLocked(/* wasCancelled= */ false);
+            recordUpdateVibrationParams(result, /* fromRequest= */ true);
         }
     }
 
     @Override
-    public int getInterfaceVersion() throws RemoteException {
+    public int getInterfaceVersion() {
         return this.VERSION;
     }
 
     @Override
-    public String getInterfaceHash() throws RemoteException {
+    public String getInterfaceHash() {
         return this.HASH;
     }
 
@@ -266,6 +286,42 @@
         }
     }
 
+    /** Write current settings into given {@link PrintWriter}. */
+    void dump(IndentingPrintWriter pw) {
+        boolean isVibratorControllerRegistered;
+        boolean hasPendingVibrationParamsRequest;
+        synchronized (mLock) {
+            isVibratorControllerRegistered =
+                    mVibratorControllerHolder.getVibratorController() != null;
+            hasPendingVibrationParamsRequest = mRequestVibrationParamsFuture != null;
+        }
+
+        pw.println("VibratorControlService:");
+        pw.increaseIndent();
+        pw.println("isVibratorControllerRegistered = " + isVibratorControllerRegistered);
+        pw.println("hasPendingVibrationParamsRequest = " + hasPendingVibrationParamsRequest);
+
+        pw.println();
+        pw.println("Vibration parameters update history:");
+        pw.increaseIndent();
+        mVibrationParamsRecords.dump(pw);
+        pw.decreaseIndent();
+
+        pw.decreaseIndent();
+    }
+
+    /** Write current settings into given {@link ProtoOutputStream}. */
+    void dump(ProtoOutputStream proto) {
+        boolean isVibratorControllerRegistered;
+        synchronized (mLock) {
+            isVibratorControllerRegistered =
+                    mVibratorControllerHolder.getVibratorController() != null;
+        }
+        proto.write(VibratorManagerServiceDumpProto.IS_VIBRATOR_CONTROLLER_REGISTERED,
+                isVibratorControllerRegistered);
+        mVibrationParamsRecords.dump(proto);
+    }
+
     /**
      * Completes or cancels the vibration params request future and resets the future and token
      * to null.
@@ -312,6 +368,33 @@
         }
     }
 
+    private static int[] mapFromAdaptiveVibrationTypeToVibrationUsages(int types) {
+        IntArray usages = new IntArray(15);
+        if ((ScaleParam.TYPE_ALARM & types) != 0) {
+            usages.add(USAGE_ALARM);
+        }
+
+        if ((ScaleParam.TYPE_NOTIFICATION & types) != 0) {
+            usages.add(USAGE_NOTIFICATION);
+            usages.add(USAGE_COMMUNICATION_REQUEST);
+        }
+
+        if ((ScaleParam.TYPE_RINGTONE & types) != 0) {
+            usages.add(USAGE_RINGTONE);
+        }
+
+        if ((ScaleParam.TYPE_MEDIA & types) != 0) {
+            usages.add(USAGE_MEDIA);
+            usages.add(USAGE_UNKNOWN);
+        }
+
+        if ((ScaleParam.TYPE_INTERACTIVE & types) != 0) {
+            usages.add(USAGE_TOUCH);
+            usages.add(USAGE_HARDWARE_FEEDBACK);
+        }
+        return usages.toArray();
+    }
+
     /**
      * Updates the adaptive haptics scales cached in {@link VibrationScaler} with the
      * provided params.
@@ -319,7 +402,14 @@
      * @param params the new vibration params.
      */
     private void updateAdaptiveHapticsScales(@Nullable VibrationParam[] params) {
+        if (params == null) {
+            return;
+        }
         for (VibrationParam param : params) {
+            if (param.getTag() != VibrationParam.scale) {
+                Slog.e(TAG, "Unsupported vibration param: " + param);
+                continue;
+            }
             ScaleParam scaleParam = param.getScale();
             updateAdaptiveHapticsScales(scaleParam.typesMask, scaleParam.scale);
         }
@@ -333,27 +423,8 @@
      * @param scale The scaling factor that should be applied to the vibrations.
      */
     private void updateAdaptiveHapticsScales(int types, float scale) {
-        if ((ScaleParam.TYPE_ALARM & types) != 0) {
-            updateOrRemoveAdaptiveHapticsScale(USAGE_ALARM, scale);
-        }
-
-        if ((ScaleParam.TYPE_NOTIFICATION & types) != 0) {
-            updateOrRemoveAdaptiveHapticsScale(USAGE_NOTIFICATION, scale);
-            updateOrRemoveAdaptiveHapticsScale(USAGE_COMMUNICATION_REQUEST, scale);
-        }
-
-        if ((ScaleParam.TYPE_RINGTONE & types) != 0) {
-            updateOrRemoveAdaptiveHapticsScale(USAGE_RINGTONE, scale);
-        }
-
-        if ((ScaleParam.TYPE_MEDIA & types) != 0) {
-            updateOrRemoveAdaptiveHapticsScale(USAGE_MEDIA, scale);
-            updateOrRemoveAdaptiveHapticsScale(USAGE_UNKNOWN, scale);
-        }
-
-        if ((ScaleParam.TYPE_INTERACTIVE & types) != 0) {
-            updateOrRemoveAdaptiveHapticsScale(USAGE_TOUCH, scale);
-            updateOrRemoveAdaptiveHapticsScale(USAGE_HARDWARE_FEEDBACK, scale);
+        for (int usage : mapFromAdaptiveVibrationTypeToVibrationUsages(types)) {
+            updateOrRemoveAdaptiveHapticsScale(usage, scale);
         }
     }
 
@@ -375,4 +446,136 @@
 
         mVibrationScaler.updateAdaptiveHapticsScale(usageHint, scale);
     }
+
+    private void recordUpdateVibrationParams(@Nullable VibrationParam[] params,
+            boolean fromRequest) {
+        if (params == null) {
+            return;
+        }
+        VibrationParamsRecords.Operation operation =
+                fromRequest ? VibrationParamsRecords.Operation.PULL
+                        : VibrationParamsRecords.Operation.PUSH;
+        long createTime = SystemClock.uptimeMillis();
+        for (VibrationParam param : params) {
+            if (param.getTag() != VibrationParam.scale) {
+                Slog.w(TAG, "Unsupported vibration param ignored from dumpsys records: " + param);
+                continue;
+            }
+            ScaleParam scaleParam = param.getScale();
+            mVibrationParamsRecords.add(new VibrationScaleParamRecord(operation, createTime,
+                    scaleParam.typesMask, scaleParam.scale));
+        }
+    }
+
+    private void recordClearVibrationParams(int typesMask) {
+        long createTime = SystemClock.uptimeMillis();
+        mVibrationParamsRecords.add(new VibrationScaleParamRecord(
+                VibrationParamsRecords.Operation.CLEAR, createTime, typesMask, NO_SCALE));
+    }
+
+    /**
+     * Keep records of {@link VibrationParam} values received by this service from a registered
+     * {@link VibratorController} and provide debug information for this service.
+     */
+    private static final class VibrationParamsRecords
+            extends GroupedAggregatedLogRecords<VibrationScaleParamRecord> {
+
+        /** The type of operations on vibration parameters that the service is recording. */
+        enum Operation {
+            PULL, PUSH, CLEAR
+        };
+
+        VibrationParamsRecords(int sizeLimit, int aggregationTimeLimit) {
+            super(sizeLimit, aggregationTimeLimit);
+        }
+
+        @Override
+        synchronized void dumpGroupHeader(IndentingPrintWriter pw, int paramType) {
+            if (paramType == VibrationParam.scale) {
+                pw.println("SCALE:");
+            } else {
+                pw.println("UNKNOWN:");
+            }
+        }
+
+        @Override
+        synchronized long findGroupKeyProtoFieldId(int usage) {
+            return VibratorManagerServiceDumpProto.PREVIOUS_VIBRATION_PARAMS;
+        }
+    }
+
+    /**
+     * Record for a single {@link Vibration.DebugInfo}, that can be grouped by usage and aggregated
+     * by UID, {@link VibrationAttributes} and {@link VibrationEffect}.
+     */
+    private static final class VibrationScaleParamRecord
+            implements GroupedAggregatedLogRecords.SingleLogRecord {
+
+        private final VibrationParamsRecords.Operation mOperation;
+        private final long mCreateTime;
+        private final int mTypesMask;
+        private final float mScale;
+
+        VibrationScaleParamRecord(VibrationParamsRecords.Operation operation, long createTime,
+                int typesMask, float scale) {
+            mOperation = operation;
+            mCreateTime = createTime;
+            mTypesMask = typesMask;
+            mScale = scale;
+        }
+
+        @Override
+        public int getGroupKey() {
+            return VibrationParam.scale;
+        }
+
+        @Override
+        public long getCreateUptimeMs() {
+            return mCreateTime;
+        }
+
+        @Override
+        public boolean mayAggregate(GroupedAggregatedLogRecords.SingleLogRecord record) {
+            if (!(record instanceof VibrationScaleParamRecord param)) {
+                return false;
+            }
+            return mTypesMask == param.mTypesMask && mOperation == param.mOperation;
+        }
+
+        @Override
+        public void dump(IndentingPrintWriter pw) {
+            String line = String.format(Locale.ROOT,
+                    "%s | %6s | scale: %5s | typesMask: %6s | usages: %s",
+                    DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)),
+                    mOperation.name().toLowerCase(Locale.ROOT),
+                    (mScale == NO_SCALE) ? "" : String.format(Locale.ROOT, "%.2f", mScale),
+                    Long.toBinaryString(mTypesMask), createVibrationUsagesString());
+            pw.println(line);
+        }
+
+        @Override
+        public void dump(ProtoOutputStream proto, long fieldId) {
+            final long token = proto.start(fieldId);
+            proto.write(VibrationParamProto.CREATE_TIME, mCreateTime);
+            proto.write(VibrationParamProto.IS_FROM_REQUEST,
+                    mOperation == VibrationParamsRecords.Operation.PULL);
+
+            final long scaleToken = proto.start(VibrationParamProto.SCALE);
+            proto.write(VibrationScaleParamProto.TYPES_MASK, mTypesMask);
+            proto.write(VibrationScaleParamProto.SCALE, mScale);
+            proto.end(scaleToken);
+
+            proto.end(token);
+        }
+
+        private String createVibrationUsagesString() {
+            StringBuilder sb = new StringBuilder();
+            int[] usages = mapFromAdaptiveVibrationTypeToVibrationUsages(mTypesMask);
+            for (int i = 0; i < usages.length; i++) {
+                if (i > 0) sb.append(", ");
+                sb.append(VibrationAttributes.usageToString(usages[i]));
+            }
+            return sb.toString();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
index f5d4d1e..6710d02 100644
--- a/services/core/java/com/android/server/vibrator/VibratorController.java
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -17,7 +17,6 @@
 package com.android.server.vibrator;
 
 import android.annotation.Nullable;
-import android.annotation.Nullable;
 import android.hardware.vibrator.IVibrator;
 import android.os.Binder;
 import android.os.IVibratorStateListener;
@@ -354,13 +353,13 @@
     }
 
     void dump(IndentingPrintWriter pw) {
-        pw.println("VibratorController:");
+        pw.println("Vibrator (id=" + mVibratorInfo.getId() + "):");
         pw.increaseIndent();
         pw.println("isVibrating = " + mIsVibrating);
         pw.println("isUnderExternalControl = " + mIsUnderExternalControl);
         pw.println("currentAmplitude = " + mCurrentAmplitude);
         pw.println("vibratorInfoLoadSuccessful = " + mVibratorInfoLoadSuccessful);
-        pw.println("vibratorStateListenerCount = "
+        pw.println("vibratorStateListener size = "
                 + mVibratorStateListeners.getRegisteredCallbackCount());
         mVibratorInfo.dump(pw);
         pw.decreaseIndent();
diff --git a/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java b/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java
index 79a99b3..b49fb85 100644
--- a/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java
+++ b/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java
@@ -24,8 +24,6 @@
 
 /**
  * Holder class for {@link IVibratorController}.
- *
- * @hide
  */
 public final class VibratorControllerHolder implements IBinder.DeathRecipient {
     private static final String TAG = "VibratorControllerHolder";
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 78e0ebb..c1bf039 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.vibrator;
 
-import static android.os.ExternalVibrationScale.ScaleLevel.SCALE_MUTE;
 import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
 import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
 
@@ -84,7 +83,6 @@
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
@@ -217,7 +215,7 @@
 
         mVibrationSettings = new VibrationSettings(mContext, mHandler);
         mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
-        mVibratorControlService = new VibratorControlService(
+        mVibratorControlService = new VibratorControlService(mContext,
                 injector.createVibratorControllerHolder(), mVibrationScaler, mVibrationSettings,
                 mLock);
         mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler);
@@ -416,14 +414,14 @@
     }
 
     @Override // Binder call
-    public void performHapticFeedback(
-            int uid, int deviceId, String opPkg, int constant, boolean always, String reason) {
+    public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant,
+            boolean always, String reason, boolean fromIme) {
         // Note that the `performHapticFeedback` method does not take a token argument from the
         // caller, and instead, uses this service as the token. This is to mitigate performance
         // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are
         // short-lived, so we don't need to cancel when the process dies.
         performHapticFeedbackInternal(
-                uid, deviceId, opPkg, constant, always, reason, /* token= */ this);
+                uid, deviceId, opPkg, constant, always, reason, /* token= */ this, fromIme);
     }
 
     /**
@@ -435,7 +433,7 @@
     @Nullable
     HalVibration performHapticFeedbackInternal(
             int uid, int deviceId, String opPkg, int constant, boolean always, String reason,
-            IBinder token) {
+            IBinder token, boolean fromIme) {
         HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider();
         if (hapticVibrationProvider == null) {
             Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready.");
@@ -449,7 +447,7 @@
         CombinedVibration combinedVibration = CombinedVibration.createParallel(effect);
         VibrationAttributes attrs =
                 hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
-                        constant, /* bypassVibrationIntensitySetting= */ always);
+                        constant, /* bypassVibrationIntensitySetting= */ always, fromIme);
         VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant);
         return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, combinedVibration, attrs,
                 "performHapticFeedback: " + reason, token);
@@ -639,13 +637,16 @@
         }
         IndentingPrintWriter pw = new IndentingPrintWriter(w, /* singleIndent= */ "  ");
         synchronized (mLock) {
-            pw.println("Vibrator Manager Service:");
+            pw.println("VibratorManagerService:");
             pw.increaseIndent();
 
             mVibrationSettings.dump(pw);
             pw.println();
 
-            pw.println("VibratorControllers:");
+            mVibrationScaler.dump(pw);
+            pw.println();
+
+            pw.println("Vibrators:");
             pw.increaseIndent();
             for (int i = 0; i < mVibrators.size(); i++) {
                 mVibrators.valueAt(i).dump(pw);
@@ -686,6 +687,10 @@
         pw.println();
         pw.println();
         mVibratorManagerRecords.dump(pw);
+
+        pw.println();
+        pw.println();
+        mVibratorControlService.dump(pw);
     }
 
     private void dumpProto(FileDescriptor fd) {
@@ -695,6 +700,7 @@
         }
         synchronized (mLock) {
             mVibrationSettings.dump(proto);
+            mVibrationScaler.dump(proto);
             if (mCurrentVibration != null) {
                 mCurrentVibration.getVibration().getDebugInfo().dump(proto,
                         VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
@@ -716,6 +722,7 @@
                     isUnderExternalControl);
         }
         mVibratorManagerRecords.dump(proto);
+        mVibratorControlService.dump(proto);
         proto.flush();
     }
 
@@ -887,7 +894,7 @@
         if (!vib.callerInfo.attrs.isFlagSet(
                 VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)) {
             // Scale resolves the default amplitudes from the effect before scaling them.
-            vib.scaleEffects(mVibrationScaler::scale);
+            vib.scaleEffects(mVibrationScaler);
         } else {
             vib.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude());
         }
@@ -1663,7 +1670,8 @@
 
         public Vibration.DebugInfo getDebugInfo() {
             return new Vibration.DebugInfo(mStatus, stats, /* playedEffect= */ null,
-                    /* originalEffect= */ null, scale.scaleLevel, callerInfo);
+                    /* originalEffect= */ null, scale.scaleLevel, scale.adaptiveHapticsScale,
+                    callerInfo);
         }
 
         public VibrationStats.StatsInfo getStatsInfo(long completionUptimeMillis) {
@@ -1739,8 +1747,9 @@
                 int aggregationTimeLimit) {
             mAggregatedVibrationHistory =
                     new VibrationRecords(aggregationSizeLimit, aggregationTimeLimit);
-            mRecentVibrations = new VibrationRecords(
-                    recentVibrationSizeLimit, /* aggregationTimeLimit= */ 0);
+            // Recent vibrations are not aggregated, to help debugging issues that just happened.
+            mRecentVibrations =
+                    new VibrationRecords(recentVibrationSizeLimit, /* aggregationTimeLimit= */ 0);
         }
 
         synchronized void record(HalVibration vib) {
@@ -1752,9 +1761,11 @@
         }
 
         private synchronized void record(Vibration.DebugInfo info) {
-            AggregatedVibrationRecord removedRecord = mRecentVibrations.record(info);
-            if (removedRecord != null) {
-                mAggregatedVibrationHistory.record(removedRecord.mLatestVibration);
+            GroupedAggregatedLogRecords.AggregatedLogRecord<VibrationRecord> droppedRecord =
+                    mRecentVibrations.add(new VibrationRecord(info));
+            if (droppedRecord != null) {
+                // Move dropped record from recent list to aggregated history list.
+                mAggregatedVibrationHistory.add(droppedRecord.getLatest());
             }
         }
 
@@ -1763,9 +1774,9 @@
             pw.increaseIndent();
             mRecentVibrations.dump(pw);
             pw.decreaseIndent();
-            pw.println();
-            pw.println();
 
+            pw.println();
+            pw.println();
             pw.println("Aggregated vibration history:");
             pw.increaseIndent();
             mAggregatedVibrationHistory.dump(pw);
@@ -1778,127 +1789,75 @@
     }
 
     /** Keep records of vibrations played and provide debug information for this service. */
-    private static final class VibrationRecords {
-        private final SparseArray<LinkedList<AggregatedVibrationRecord>> mVibrations =
-                new SparseArray<>();
-        private final int mSizeLimit;
-        private final int mAggregationTimeLimit;
+    private static final class VibrationRecords
+            extends GroupedAggregatedLogRecords<VibrationRecord> {
 
         VibrationRecords(int sizeLimit, int aggregationTimeLimit) {
-            mSizeLimit = sizeLimit;
-            mAggregationTimeLimit = aggregationTimeLimit;
+            super(sizeLimit, aggregationTimeLimit);
         }
 
-        synchronized AggregatedVibrationRecord record(Vibration.DebugInfo info) {
-            int usage = info.mCallerInfo.attrs.getUsage();
-            if (!mVibrations.contains(usage)) {
-                mVibrations.put(usage, new LinkedList<>());
-            }
-            LinkedList<AggregatedVibrationRecord> records = mVibrations.get(usage);
-            if (mAggregationTimeLimit > 0 && !records.isEmpty()) {
-                AggregatedVibrationRecord lastRecord = records.getLast();
-                if (lastRecord.mayAggregate(info, mAggregationTimeLimit)) {
-                    lastRecord.record(info);
-                    return null;
-                }
-            }
-            AggregatedVibrationRecord removedRecord = null;
-            if (records.size() > mSizeLimit) {
-                removedRecord = records.removeFirst();
-            }
-            records.addLast(new AggregatedVibrationRecord(info));
-            return removedRecord;
+        @Override
+        void dumpGroupHeader(IndentingPrintWriter pw, int usage) {
+            pw.println(VibrationAttributes.usageToString(usage) + ":");
         }
 
-        synchronized void dump(IndentingPrintWriter pw) {
-            for (int i = 0; i < mVibrations.size(); i++) {
-                pw.println(VibrationAttributes.usageToString(mVibrations.keyAt(i)) + ":");
-                pw.increaseIndent();
-                for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) {
-                    info.dump(pw);
-                }
-                pw.decreaseIndent();
-                pw.println();
-            }
-        }
-
-        synchronized void dump(ProtoOutputStream proto) {
-            for (int i = 0; i < mVibrations.size(); i++) {
-                long fieldId;
-                switch (mVibrations.keyAt(i)) {
-                    case VibrationAttributes.USAGE_RINGTONE:
-                        fieldId = VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS;
-                        break;
-                    case VibrationAttributes.USAGE_NOTIFICATION:
-                        fieldId = VibratorManagerServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS;
-                        break;
-                    case VibrationAttributes.USAGE_ALARM:
-                        fieldId = VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS;
-                        break;
-                    default:
-                        fieldId = VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS;
-                }
-                for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) {
-                    if (info.mLatestVibration.mPlayedEffect == null) {
-                        // External vibrations are reported separately in the dump proto
-                        info.dump(proto,
-                                VibratorManagerServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS);
-                    } else {
-                        info.dump(proto, fieldId);
-                    }
-                }
-            }
-        }
-
-        synchronized void dumpOnSingleField(ProtoOutputStream proto, long fieldId) {
-            for (int i = 0; i < mVibrations.size(); i++) {
-                for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) {
-                    info.dump(proto, fieldId);
-                }
-            }
+        @Override
+        long findGroupKeyProtoFieldId(int usage) {
+            return switch (usage) {
+                case VibrationAttributes.USAGE_RINGTONE ->
+                    VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS;
+                case VibrationAttributes.USAGE_NOTIFICATION ->
+                    VibratorManagerServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS;
+                case VibrationAttributes.USAGE_ALARM ->
+                    VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS;
+                default ->
+                    VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS;
+            };
         }
     }
 
     /**
-     * Record that keeps the last {@link Vibration.DebugInfo} played, aggregating close vibrations
-     * from the same uid that have the same {@link VibrationAttributes} and {@link VibrationEffect}.
+     * Record for a single {@link Vibration.DebugInfo}, that can be grouped by usage and aggregated
+     * by UID, {@link VibrationAttributes} and {@link VibrationEffect}.
      */
-    private static final class AggregatedVibrationRecord {
-        private final Vibration.DebugInfo mFirstVibration;
-        private Vibration.DebugInfo mLatestVibration;
-        private int mVibrationCount;
+    private static final class VibrationRecord
+            implements GroupedAggregatedLogRecords.SingleLogRecord {
+        private final Vibration.DebugInfo mInfo;
 
-        AggregatedVibrationRecord(Vibration.DebugInfo info) {
-            mLatestVibration = mFirstVibration = info;
-            mVibrationCount = 1;
+        VibrationRecord(Vibration.DebugInfo info) {
+            mInfo = info;
         }
 
-        synchronized boolean mayAggregate(Vibration.DebugInfo info, long timeLimit) {
-            return Objects.equals(mLatestVibration.mCallerInfo.uid, info.mCallerInfo.uid)
-                    && Objects.equals(mLatestVibration.mCallerInfo.attrs, info.mCallerInfo.attrs)
-                    && Objects.equals(mLatestVibration.mPlayedEffect, info.mPlayedEffect)
-                    && Math.abs(mLatestVibration.mCreateTime - info.mCreateTime) < timeLimit;
+        @Override
+        public int getGroupKey() {
+            return mInfo.mCallerInfo.attrs.getUsage();
         }
 
-        synchronized void record(Vibration.DebugInfo vib) {
-            mLatestVibration = vib;
-            mVibrationCount++;
+        @Override
+        public long getCreateUptimeMs() {
+            return mInfo.mCreateTime;
         }
 
-        synchronized void dump(IndentingPrintWriter pw) {
-            mFirstVibration.dumpCompact(pw);
-            if (mVibrationCount == 1) {
-                return;
+        @Override
+        public boolean mayAggregate(GroupedAggregatedLogRecords.SingleLogRecord record) {
+            if (!(record instanceof VibrationRecord)) {
+                return false;
             }
-            if (mVibrationCount > 2) {
-                pw.println(
-                        "-> Skipping " + (mVibrationCount - 2) + " aggregated vibrations, latest:");
-            }
-            mLatestVibration.dumpCompact(pw);
+            Vibration.DebugInfo info = ((VibrationRecord) record).mInfo;
+            return mInfo.mCallerInfo.uid == info.mCallerInfo.uid
+                    && Objects.equals(mInfo.mCallerInfo.attrs, info.mCallerInfo.attrs)
+                    && Objects.equals(mInfo.mPlayedEffect, info.mPlayedEffect);
         }
 
-        synchronized void dump(ProtoOutputStream proto, long fieldId) {
-            mLatestVibration.dump(proto, fieldId);
+        @Override
+        public void dump(IndentingPrintWriter pw) {
+            // Prints a compact version of each vibration request for dumpsys.
+            mInfo.dumpCompact(pw);
+        }
+
+        @Override
+        public void dump(ProtoOutputStream proto, long fieldId) {
+            mInfo.dump(proto, fieldId);
         }
     }
 
@@ -2001,7 +1960,6 @@
 
         @Override
         public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) {
-
             if (!hasExternalControlCapability()) {
                 return SCALE_MUTE;
             }
@@ -2085,10 +2043,9 @@
                 }
                 mCurrentExternalVibration = vibHolder;
                 vibHolder.linkToDeath();
-                vibHolder.scale.scaleLevel = mVibrationScaler.getExternalVibrationScaleLevel(
-                        attrs.getUsage());
-                vibHolder.scale.adaptiveHapticsScale = mVibrationScaler.getAdaptiveHapticsScale(
-                        attrs.getUsage());
+                vibHolder.scale.scaleLevel = mVibrationScaler.getScaleLevel(attrs.getUsage());
+                vibHolder.scale.adaptiveHapticsScale =
+                        mVibrationScaler.getAdaptiveHapticsScale(attrs.getUsage());
             }
 
             if (waitForCompletion) {
@@ -2300,7 +2257,7 @@
             HalVibration vib = performHapticFeedbackInternal(Binder.getCallingUid(),
                     Context.DEVICE_ID_DEFAULT, SHELL_PACKAGE_NAME, constant,
                     /* always= */ commonOptions.force, /* reason= */ commonOptions.description,
-                    deathBinder);
+                    deathBinder, false /* fromIme */);
             maybeWaitOnVibration(vib, commonOptions);
 
             return 0;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 90cff39..92fde18 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1476,7 +1476,8 @@
         }
     }
 
-    private void scheduleConfigurationChanged(Configuration config) {
+    private void scheduleConfigurationChanged(@NonNull Configuration config,
+            @NonNull ActivityWindowInfo activityWindowInfo) {
         if (!attachedToProcess()) {
             ProtoLog.w(WM_DEBUG_CONFIGURATION, "Can't report activity configuration "
                     + "update - client not running, activityRecord=%s", this);
@@ -1487,7 +1488,7 @@
                     + "config: %s", this, config);
 
             mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(),
-                    ActivityConfigurationChangeItem.obtain(token, config));
+                    ActivityConfigurationChangeItem.obtain(token, config, activityWindowInfo));
         } catch (RemoteException e) {
             // If process died, whatever.
         }
@@ -9785,7 +9786,11 @@
         // configurations because there are cases (like moving a task to the root pinned task) where
         // the combine configurations are equal, but would otherwise differ in the override config
         mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
-        if (getConfiguration().equals(mTmpConfig) && !displayChanged) {
+        final ActivityWindowInfo newActivityWindowInfo = getActivityWindowInfo();
+        final boolean isActivityWindowInfoChanged = Flags.activityWindowInfoFlag()
+                && !mLastReportedActivityWindowInfo.equals(newActivityWindowInfo);
+        if (!displayChanged && !isActivityWindowInfoChanged
+                && getConfiguration().equals(mTmpConfig)) {
             ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
                     + "unchanged in %s", this);
             return true;
@@ -9800,7 +9805,6 @@
 
         // Update last reported values.
         final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
-        final ActivityWindowInfo newActivityWindowInfo = getActivityWindowInfo();
 
         setLastReportedConfiguration(getProcessGlobalConfiguration(), newMergedOverrideConfig);
         setLastReportedActivityWindowInfo(newActivityWindowInfo);
@@ -9823,7 +9827,7 @@
                 scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig,
                         newActivityWindowInfo);
             } else {
-                scheduleConfigurationChanged(newMergedOverrideConfig);
+                scheduleConfigurationChanged(newMergedOverrideConfig, newActivityWindowInfo);
             }
             notifyDisplayCompatPolicyAboutConfigurationChange(
                     mLastReportedConfiguration.getMergedConfiguration(), mTmpConfig);
@@ -9891,7 +9895,7 @@
             scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig,
                     newActivityWindowInfo);
         } else {
-            scheduleConfigurationChanged(newMergedOverrideConfig);
+            scheduleConfigurationChanged(newMergedOverrideConfig, newActivityWindowInfo);
         }
         notifyDisplayCompatPolicyAboutConfigurationChange(
                 mLastReportedConfiguration.getMergedConfiguration(), mTmpConfig);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index cd96806..fa76774 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -520,11 +520,37 @@
         updateVisibility();
         mControl = new InsetsSourceControl(mSource.getId(), mSource.getType(), leash,
                 mClientVisible, surfacePosition, getInsetsHint());
+        mStateController.notifySurfaceTransactionReady(this, getSurfaceTransactionId(leash), true);
 
         ProtoLog.d(WM_DEBUG_WINDOW_INSETS,
                 "InsetsSource Control %s for target %s", mControl, mControlTarget);
     }
 
+    private long getSurfaceTransactionId(SurfaceControl leash) {
+        // Here returns mNativeObject (long) as the ID instead of the leash itself so that
+        // InsetsStateController won't keep referencing the leash unexpectedly.
+        return leash != null ? leash.mNativeObject : 0;
+    }
+
+    /**
+     * This is called when the surface transaction of the leash initialization has been committed.
+     *
+     * @param id Indicates which transaction is committed so that stale callbacks can be dropped.
+     */
+    void onSurfaceTransactionCommitted(long id) {
+        if (mIsLeashReadyForDispatching) {
+            return;
+        }
+        if (mControl == null) {
+            return;
+        }
+        if (id != getSurfaceTransactionId(mControl.getLeash())) {
+            return;
+        }
+        mIsLeashReadyForDispatching = true;
+        mStateController.notifySurfaceTransactionReady(this, 0, false);
+    }
+
     void startSeamlessRotation() {
         if (!mSeamlessRotating) {
             mSeamlessRotating = true;
@@ -545,10 +571,6 @@
         return true;
     }
 
-    void onSurfaceTransactionApplied() {
-        mIsLeashReadyForDispatching = true;
-    }
-
     void setClientVisible(boolean clientVisible) {
         if (mClientVisible == clientVisible) {
             return;
@@ -733,6 +755,7 @@
         public void onAnimationCancelled(SurfaceControl animationLeash) {
             if (mAdapter == this) {
                 mStateController.notifyControlRevoked(mControlTarget, InsetsSourceProvider.this);
+                mStateController.notifySurfaceTransactionReady(InsetsSourceProvider.this, 0, false);
                 mControl = null;
                 mControlTarget = null;
                 mAdapter = null;
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 6b9fcf4..ba578f6 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -34,6 +34,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.SparseArray;
+import android.util.SparseLongArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
@@ -58,6 +59,7 @@
     private final DisplayContent mDisplayContent;
 
     private final SparseArray<InsetsSourceProvider> mProviders = new SparseArray<>();
+    private final SparseLongArray mSurfaceTransactionIds = new SparseLongArray();
     private final ArrayMap<InsetsControlTarget, ArrayList<InsetsSourceProvider>>
             mControlTargetProvidersMap = new ArrayMap<>();
     private final SparseArray<InsetsControlTarget> mIdControlTargetMap = new SparseArray<>();
@@ -360,14 +362,32 @@
         notifyPendingInsetsControlChanged();
     }
 
+    void notifySurfaceTransactionReady(InsetsSourceProvider provider, long id, boolean ready) {
+        if (ready) {
+            mSurfaceTransactionIds.put(provider.getSource().getId(), id);
+        } else {
+            mSurfaceTransactionIds.delete(provider.getSource().getId());
+        }
+    }
+
     private void notifyPendingInsetsControlChanged() {
         if (mPendingControlChanged.isEmpty()) {
             return;
         }
+        final int size = mSurfaceTransactionIds.size();
+        final SparseLongArray surfaceTransactionIds = new SparseLongArray(size);
+        for (int i = 0; i < size; i++) {
+            surfaceTransactionIds.append(
+                    mSurfaceTransactionIds.keyAt(i), mSurfaceTransactionIds.valueAt(i));
+        }
         mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
-            for (int i = mProviders.size() - 1; i >= 0; i--) {
-                final InsetsSourceProvider provider = mProviders.valueAt(i);
-                provider.onSurfaceTransactionApplied();
+            for (int i = 0; i < size; i++) {
+                final int sourceId = surfaceTransactionIds.keyAt(i);
+                final InsetsSourceProvider provider = mProviders.get(sourceId);
+                if (provider == null) {
+                    continue;
+                }
+                provider.onSurfaceTransactionCommitted(surfaceTransactionIds.valueAt(i));
             }
             final ArraySet<InsetsControlTarget> newControlTargets = new ArraySet<>();
             int displayId = mDisplayContent.getDisplayId();
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 908cbd3..30134d8 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -336,19 +336,19 @@
     }
 
     @Override
-    public boolean performHapticFeedback(int effectId, boolean always) {
+    public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) {
         final long ident = Binder.clearCallingIdentity();
         try {
             return mService.mPolicy.performHapticFeedback(mUid, mPackageName,
-                        effectId, always, null);
+                        effectId, always, null, fromIme);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
     @Override
-    public void performHapticFeedbackAsync(int effectId, boolean always) {
-        performHapticFeedback(effectId, always);
+    public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) {
+        performHapticFeedback(effectId, always, fromIme);
     }
 
     /* Drag/drop */
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index b43a454..5e7f1cb 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -28,6 +28,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.content.Context;
+import android.os.HandlerExecutor;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -69,6 +70,8 @@
 
     private Choreographer mChoreographer;
 
+    private final HandlerExecutor mExecutor;
+
     /**
      * Indicates whether we have an animation frame callback scheduled, which will happen at
      * vsync-app and then schedule the animation tick at the right time (vsync-sf).
@@ -80,8 +83,7 @@
      * A list of runnable that need to be run after {@link WindowContainer#prepareSurfaces} is
      * executed and the corresponding transaction is closed and applied.
      */
-    private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();
-    private boolean mInExecuteAfterPrepareSurfacesRunnables;
+    private ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();
 
     private final SurfaceControl.Transaction mTransaction;
 
@@ -92,6 +94,7 @@
         mTransaction = service.mTransactionFactory.get();
         service.mAnimationHandler.runWithScissors(
                 () -> mChoreographer = Choreographer.getSfInstance(), 0 /* timeout */);
+        mExecutor = new HandlerExecutor(service.mAnimationHandler);
 
         mAnimationFrameCallback = frameTimeNs -> {
             synchronized (mService.mGlobalLock) {
@@ -197,6 +200,19 @@
             updateRunningExpensiveAnimationsLegacy();
         }
 
+        final ArrayList<Runnable> afterPrepareSurfacesRunnables = mAfterPrepareSurfacesRunnables;
+        if (!afterPrepareSurfacesRunnables.isEmpty()) {
+            mAfterPrepareSurfacesRunnables = new ArrayList<>();
+            mTransaction.addTransactionCommittedListener(mExecutor, () -> {
+                synchronized (mService.mGlobalLock) {
+                    // Traverse in order they were added.
+                    for (int i = 0, size = afterPrepareSurfacesRunnables.size(); i < size; i++) {
+                        afterPrepareSurfacesRunnables.get(i).run();
+                    }
+                    afterPrepareSurfacesRunnables.clear();
+                }
+            });
+        }
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyTransaction");
         mTransaction.apply();
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
@@ -204,7 +220,6 @@
         ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
 
         mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
-        executeAfterPrepareSurfacesRunnables();
 
         if (DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: exit"
@@ -286,34 +301,10 @@
 
     /**
      * Adds a runnable to be executed after {@link WindowContainer#prepareSurfaces} is called and
-     * the corresponding transaction is closed and applied.
+     * the corresponding transaction is closed, applied, and committed.
      */
     void addAfterPrepareSurfacesRunnable(Runnable r) {
-        // If runnables are already being handled in executeAfterPrepareSurfacesRunnable, then just
-        // immediately execute the runnable passed in.
-        if (mInExecuteAfterPrepareSurfacesRunnables) {
-            r.run();
-            return;
-        }
-
         mAfterPrepareSurfacesRunnables.add(r);
         scheduleAnimation();
     }
-
-    void executeAfterPrepareSurfacesRunnables() {
-
-        // Don't even think about to start recursing!
-        if (mInExecuteAfterPrepareSurfacesRunnables) {
-            return;
-        }
-        mInExecuteAfterPrepareSurfacesRunnables = true;
-
-        // Traverse in order they were added.
-        final int size = mAfterPrepareSurfacesRunnables.size();
-        for (int i = 0; i < size; i++) {
-            mAfterPrepareSurfacesRunnables.get(i).run();
-        }
-        mAfterPrepareSurfacesRunnables.clear();
-        mInExecuteAfterPrepareSurfacesRunnables = false;
-    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c93cc07..7e061298 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6706,7 +6706,7 @@
 
     private void dumpLogStatus(PrintWriter pw) {
         pw.println("WINDOW MANAGER LOGGING (dumpsys window logging)");
-        if (android.tracing.Flags.perfettoProtolog()) {
+        if (android.tracing.Flags.perfettoProtologTracing()) {
             pw.println("Deprecated legacy command. Use Perfetto commands instead.");
             return;
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a7a28c2..18ac0e7 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2041,6 +2041,13 @@
         if (!isVisible()) {
             return;
         }
+        final WallpaperWindowToken wallpaperToken = mToken.asWallpaperToken();
+        if (wallpaperToken != null) {
+            if (wallpaperToken.hasVisibleNotDrawnWallpaper()) {
+                outWaitingForDrawn.add(this);
+            }
+            return;
+        }
         if (mActivityRecord != null) {
             if (!mActivityRecord.isVisibleRequested()) return;
             if (mActivityRecord.allDrawn) {
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index 424d504..6d5fc80 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -155,13 +155,13 @@
             logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
             writeTraceToFileLocked();
             logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
-            if (!android.tracing.Flags.perfettoProtolog()) {
+            if (!android.tracing.Flags.perfettoProtologTracing()) {
                 ((LegacyProtoLogImpl) mProtoLog).stopProtoLog(pw, true);
             }
             logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
             mBuffer.resetBuffer();
             mEnabled = mEnabledLockFree = true;
-            if (!android.tracing.Flags.perfettoProtolog()) {
+            if (!android.tracing.Flags.perfettoProtologTracing()) {
                 ((LegacyProtoLogImpl) mProtoLog).startProtoLog(pw);
             }
         }
diff --git a/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp b/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp
index 9a509a7..c337523 100644
--- a/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp
+++ b/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp
@@ -40,7 +40,7 @@
 } // anonymous namespace
 
 static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawDescSize(
-        JNIEnv* env, jobject thiz, int fd) {
+        JNIEnv* env, jclass /*clazz*/, int fd) {
     int size = 0;
     if (ioctl(fd, HIDIOCGRDESCSIZE, &size) < 0) {
         return -1;
@@ -49,7 +49,7 @@
 }
 
 static jbyteArray com_android_server_accessibility_BrailleDisplayConnection_getHidrawDesc(
-        JNIEnv* env, jobject thiz, int fd, int descSize) {
+        JNIEnv* env, jclass /*clazz*/, int fd, int descSize) {
     struct hidraw_report_descriptor desc;
     desc.size = descSize;
     if (ioctl(fd, HIDIOCGRDESC, &desc) < 0) {
@@ -63,9 +63,8 @@
     return result;
 }
 
-static jstring com_android_server_accessibility_BrailleDisplayConnection_getHidrawUniq(JNIEnv* env,
-                                                                                       jobject thiz,
-                                                                                       int fd) {
+static jstring com_android_server_accessibility_BrailleDisplayConnection_getHidrawUniq(
+        JNIEnv* env, jclass /*clazz*/, int fd) {
     char buf[UNIQ_SIZE_MAX];
     if (ioctl(fd, HIDIOCGRAWUNIQ(UNIQ_SIZE_MAX), buf) < 0) {
         return nullptr;
@@ -74,9 +73,8 @@
     return env->NewStringUTF(buf);
 }
 
-static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawBusType(JNIEnv* env,
-                                                                                       jobject thiz,
-                                                                                       int fd) {
+static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawBusType(
+        JNIEnv* env, jclass /*clazz*/, int fd) {
     struct hidraw_devinfo info;
     if (ioctl(fd, HIDIOCGRAWINFO, &info) < 0) {
         return -1;
diff --git a/services/fakes/java/com/android/server/example/BlueManagerService.java b/services/fakes/java/com/android/server/example/BlueManagerService.java
new file mode 100644
index 0000000..8e3c8d7
--- /dev/null
+++ b/services/fakes/java/com/android/server/example/BlueManagerService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.example;
+
+import android.content.Context;
+import android.os.Binder;
+import android.ravenwood.example.BlueManager;
+
+import com.android.server.SystemService;
+
+public class BlueManagerService extends Binder {
+    public static class Lifecycle extends SystemService {
+        private BlueManagerService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mService = new BlueManagerService();
+            publishBinderService(BlueManager.SERVICE_NAME, mService);
+        }
+    }
+
+    @Override
+    public String getInterfaceDescriptor() {
+        return "blue";
+    }
+}
diff --git a/services/fakes/java/com/android/server/example/RedManagerService.java b/services/fakes/java/com/android/server/example/RedManagerService.java
new file mode 100644
index 0000000..e0be733
--- /dev/null
+++ b/services/fakes/java/com/android/server/example/RedManagerService.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.example;
+
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.ravenwood.example.BlueManager;
+import android.ravenwood.example.RedManager;
+
+import com.android.server.SystemService;
+
+import java.util.List;
+
+public class RedManagerService extends Binder {
+    private IBinder mBlueService;
+
+    public static class Lifecycle extends SystemService {
+        private RedManagerService mService;
+
+        public Lifecycle(Context context) {
+            super(context, List.of(BlueManager.class));
+        }
+
+        @Override
+        public void onStart() {
+            mService = new RedManagerService();
+            publishBinderService(RedManager.SERVICE_NAME, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == PHASE_SYSTEM_SERVICES_READY) {
+                mService.mBlueService = getBinderService(BlueManager.SERVICE_NAME);
+            }
+        }
+    }
+
+    @Override
+    public String getInterfaceDescriptor() {
+        try {
+            // Obtain the answer from dependency, but then augment it to prove that the answer
+            // was channeled through us
+            return mBlueService.getInterfaceDescriptor() + "+red";
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
index b9d89c2..28889de 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionFlags.kt
@@ -347,7 +347,8 @@
     }
 
     fun isAppOpGranted(flags: Int): Boolean =
-        isPermissionGranted(flags) && !flags.hasBits(APP_OP_REVOKED)
+        isPermissionGranted(flags) && !flags.hasBits(RESTRICTION_REVOKED) &&
+            !flags.hasBits(APP_OP_REVOKED)
 
     fun toApiFlags(flags: Int): Int {
         var apiFlags = 0
diff --git a/services/tests/VpnTests/Android.bp b/services/tests/VpnTests/Android.bp
new file mode 100644
index 0000000..6ad27fc
--- /dev/null
+++ b/services/tests/VpnTests/Android.bp
@@ -0,0 +1,22 @@
+//########################################################################
+// Build FrameworksVpnTests package
+//########################################################################
+package {
+    default_team: "trendy_team_fwk_core_networking",
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "Android-Apache-2.0"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "FrameworksVpnTests",
+    srcs: [
+        "java/**/*.java",
+        "java/**/*.kt",
+    ],
+
+    test_suites: ["device-tests"],
+}
diff --git a/services/tests/VpnTests/AndroidManifest.xml b/services/tests/VpnTests/AndroidManifest.xml
new file mode 100644
index 0000000..d884084
--- /dev/null
+++ b/services/tests/VpnTests/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.frameworks.tests.vpn">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.tests.vpn"
+        android:label="Frameworks VPN Tests" />
+</manifest>
\ No newline at end of file
diff --git a/services/tests/VpnTests/AndroidTest.xml b/services/tests/VpnTests/AndroidTest.xml
new file mode 100644
index 0000000..ebeeac7
--- /dev/null
+++ b/services/tests/VpnTests/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration description="Runs VPN Tests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="FrameworksVpnTests.apk" />
+    </target_preparer>
+
+    <option name="test-tag" value="FrameworksVpnTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.tests.vpn" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/services/tests/VpnTests/OWNERS b/services/tests/VpnTests/OWNERS
new file mode 100644
index 0000000..45ea251
--- /dev/null
+++ b/services/tests/VpnTests/OWNERS
@@ -0,0 +1,2 @@
+set noparent
+file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
\ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
index 060f99b..397d77c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display.brightness;
 
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
 
 import static org.junit.Assert.assertEquals;
@@ -43,6 +45,7 @@
                 getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER));
         mBrightnessEvent.setPhysicalDisplayId("test");
         mBrightnessEvent.setDisplayState(Display.STATE_ON);
+        mBrightnessEvent.setDisplayPolicy(POLICY_BRIGHT);
         mBrightnessEvent.setLux(100.0f);
         mBrightnessEvent.setPreThresholdLux(150.0f);
         mBrightnessEvent.setTime(System.currentTimeMillis());
@@ -74,11 +77,12 @@
     public void testToStringWorksAsExpected() {
         String actualString = mBrightnessEvent.toString(false);
         String expectedString =
-                "BrightnessEvent: disp=1, physDisp=test, displayState=ON, brt=0.6, initBrt=25.0,"
-                + " rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150.0, hbmMax=0.62, hbmMode=off,"
-                + " rbcStrength=-1, thrmMax=0.65, powerFactor=0.2, wasShortTermModelActive=true,"
-                + " flags=, reason=doze [ low_pwr ], autoBrightness=true, strategy="
-                        + DISPLAY_BRIGHTNESS_STRATEGY_NAME + ", autoBrightnessMode=idle";
+                "BrightnessEvent: disp=1, physDisp=test, displayState=ON, displayPolicy=BRIGHT,"
+                + " brt=0.6, initBrt=25.0, rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150.0,"
+                + " hbmMax=0.62, hbmMode=off, rbcStrength=-1, thrmMax=0.65, powerFactor=0.2,"
+                + " wasShortTermModelActive=true, flags=, reason=doze [ low_pwr ],"
+                + " autoBrightness=true, strategy=" + DISPLAY_BRIGHTNESS_STRATEGY_NAME
+                + ", autoBrightnessMode=idle";
         assertEquals(expectedString, actualString);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
index aec3f45..344e2c2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
@@ -103,7 +103,7 @@
                 }
 
                 BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                        mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                        BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
                 assertThat(scanner.getHidrawNodePaths(testDir.toPath()))
                         .containsExactly(hidrawNode0, hidrawNode1);
@@ -123,7 +123,7 @@
                     descriptor);
 
             BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                    mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                    BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
             assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isEqualTo(descriptor);
         }
@@ -133,7 +133,7 @@
             when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(0);
 
             BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                    mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                    BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
             assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isNull();
         }
@@ -144,7 +144,7 @@
             when(mNativeInterface.getHidrawUniq(anyInt())).thenReturn(macAddress);
 
             BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                    mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                    BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
             assertThat(scanner.getUniqueId(NULL_PATH)).isEqualTo(macAddress);
         }
@@ -155,7 +155,7 @@
                     .thenReturn(BrailleDisplayConnection.BUS_USB);
 
             BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                    mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                    BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
             assertThat(scanner.getDeviceBusType(NULL_PATH))
                     .isEqualTo(BrailleDisplayConnection.BUS_USB);
@@ -167,7 +167,7 @@
                     .thenReturn(BrailleDisplayConnection.BUS_BLUETOOTH);
 
             BrailleDisplayConnection.BrailleDisplayScanner scanner =
-                    mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+                    BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
 
             assertThat(scanner.getDeviceBusType(NULL_PATH))
                     .isEqualTo(BrailleDisplayConnection.BUS_BLUETOOTH);
diff --git a/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java
index 08a6529..a80a8ec 100644
--- a/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java
@@ -24,6 +24,7 @@
 import static com.android.server.adaptiveauth.AdaptiveAuthService.MAX_ALLOWED_FAILED_AUTH_ATTEMPTS;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -32,6 +33,7 @@
 
 import android.app.KeyguardManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.biometrics.AuthenticationStateListener;
 import android.hardware.biometrics.BiometricManager;
 import android.os.RemoteException;
@@ -103,6 +105,10 @@
         mSetFlagsRule.enableFlags(FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS);
 
         mContext = spy(ApplicationProvider.getApplicationContext());
+
+        assumeTrue("Adaptive auth is disabled on device",
+                !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+
         when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
         when(mContext.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager);
 
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
index 5fe60d7..b012aaa 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
@@ -16,18 +16,26 @@
 
 package com.android.server.contentprotection;
 
+import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
+import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_ENABLED;
+import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY;
+import static android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.admin.DevicePolicyCache;
 import android.app.admin.DevicePolicyManagerInternal;
-import android.content.ContentResolver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.UserHandle;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.testing.TestableContentResolver;
 import android.testing.TestableContext;
@@ -36,6 +44,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.server.LocalServices;
+
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -78,29 +89,23 @@
     public final TestableContext mTestableContext =
             new TestableContext(ApplicationProvider.getApplicationContext());
 
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private final TestableContentResolver mTestableContentResolver =
             mTestableContext.getContentResolver();
 
-    @Mock private ContentResolver mMockContentResolver;
-
     @Mock private DevicePolicyManagerInternal mMockDevicePolicyManagerInternal;
 
-    @Test
-    public void constructor_registersContentObserver() {
-        ContentProtectionConsentManager manager =
-                createContentProtectionConsentManager(mMockContentResolver);
+    @Mock private DevicePolicyCache mMockDevicePolicyCache;
 
-        assertThat(manager.mContentObserver).isNotNull();
-        verify(mMockContentResolver)
-                .registerContentObserver(
-                        URI_PACKAGE_VERIFIER_USER_CONSENT,
-                        /* notifyForDescendants= */ false,
-                        manager.mContentObserver,
-                        UserHandle.USER_ALL);
+    @Before
+    public void setup() {
+        setupLocalService(DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal);
     }
 
     @Test
-    public void isConsentGranted_packageVerifierNotGranted() {
+    public void isConsentGranted_policyFlagDisabled_packageVerifierNotGranted() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
                 createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE);
 
@@ -108,10 +113,25 @@
 
         assertThat(actual).isFalse();
         verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void isConsentGranted_contentProtectionNotGranted() {
+    public void isConsentGranted_policyFlagEnabled_packageVerifierNotGranted() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isFalse();
+        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagDisabled_contentProtectionNotGranted() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
                 createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
 
@@ -119,10 +139,12 @@
 
         assertThat(actual).isFalse();
         verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void isConsentGranted_packageVerifierGranted_userNotManaged() {
+    public void isConsentGranted_policyFlagDisabled_packageVerifierGranted_userNotManaged() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
                 createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE);
 
@@ -130,10 +152,12 @@
 
         assertThat(actual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void isConsentGranted_packageVerifierGranted_userManaged() {
+    public void isConsentGranted_policyFlagDisabled_packageVerifierGranted_userManaged() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
                 .thenReturn(true);
         ContentProtectionConsentManager manager =
@@ -142,21 +166,110 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void isConsentGranted_packageVerifierDefault() {
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userNotManaged_contentProtectionNotGranted() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
-                createContentProtectionConsentManager(VALUE_DEFAULT, VALUE_TRUE);
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
 
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void isConsentGranted_contentProtectionDefault() {
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userNotManaged_contentProtectionGranted() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyDisabled() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
+                .thenReturn(true);
+        when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID))
+                .thenReturn(CONTENT_PROTECTION_DISABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isFalse();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyEnabled() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
+                .thenReturn(true);
+        when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID))
+                .thenReturn(CONTENT_PROTECTION_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionGranted() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
+                .thenReturn(true);
+        when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID))
+                .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionNotGranted() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
+                .thenReturn(true);
+        when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID))
+                .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isFalse();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID);
+    }
+
+    @Test
+    public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionDefault() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID))
+                .thenReturn(true);
+        when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID))
+                .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY);
         ContentProtectionConsentManager manager =
                 createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT);
 
@@ -164,60 +277,150 @@
 
         assertThat(actual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID);
     }
 
     @Test
-    public void contentObserver_packageVerifier() {
+    public void isConsentGranted_policyFlagDisabled_packageVerifierDefault() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
-                createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT);
-        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+                createContentProtectionConsentManager(VALUE_DEFAULT, VALUE_TRUE);
 
-        notifyContentObserver(
-                manager,
-                URI_PACKAGE_VERIFIER_USER_CONSENT,
-                KEY_PACKAGE_VERIFIER_USER_CONSENT,
-                VALUE_FALSE);
-        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
-        assertThat(firstActual).isTrue();
-        assertThat(secondActual).isFalse();
-        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        assertThat(actual).isFalse();
+        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
     @Test
-    public void contentObserver_contentProtection() {
+    public void isConsentGranted_policyFlagEnabled_packageVerifierDefault() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
         ContentProtectionConsentManager manager =
-                createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT);
-        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+                createContentProtectionConsentManager(VALUE_DEFAULT, VALUE_TRUE);
 
-        notifyContentObserver(
-                manager,
-                URI_CONTENT_PROTECTION_USER_CONSENT,
-                KEY_CONTENT_PROTECTION_USER_CONSENT,
-                VALUE_FALSE);
-        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
-        assertThat(firstActual).isTrue();
-        assertThat(secondActual).isFalse();
-        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        assertThat(actual).isFalse();
+        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
+        verifyZeroInteractions(mMockDevicePolicyCache);
     }
 
-    private void notifyContentObserver(
-            ContentProtectionConsentManager manager, Uri uri, String key, int value) {
+    @Test
+    public void isConsentGranted_policyFlagDisabled_contentProtectionDefault() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT);
+
+        boolean actual = manager.isConsentGranted(TEST_USER_ID);
+
+        assertThat(actual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void contentObserver_policyFlagDisabled_packageVerifier() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE);
+
+        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(firstActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        putGlobalSettings(KEY_PACKAGE_VERIFIER_USER_CONSENT, VALUE_TRUE);
+        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(secondActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        notifyContentObserver(manager, URI_PACKAGE_VERIFIER_USER_CONSENT);
+        boolean thirdActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(thirdActual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void contentObserver_policyFlagEnabled_packageVerifier() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE);
+
+        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(firstActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        putGlobalSettings(KEY_PACKAGE_VERIFIER_USER_CONSENT, VALUE_TRUE);
+        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(secondActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        notifyContentObserver(manager, URI_PACKAGE_VERIFIER_USER_CONSENT);
+        boolean thirdActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(thirdActual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void contentObserver_policyFlagDisabled_contentProtection() {
+        mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
+
+        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(firstActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        putGlobalSettings(KEY_CONTENT_PROTECTION_USER_CONSENT, VALUE_TRUE);
+        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(secondActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt());
+
+        notifyContentObserver(manager, URI_CONTENT_PROTECTION_USER_CONSENT);
+        boolean thirdActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(thirdActual).isTrue();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    @Test
+    public void contentObserver_policyFlagEnabled_contentProtection() {
+        mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED);
+        ContentProtectionConsentManager manager =
+                createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE);
+
+        boolean firstActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(firstActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
+
+        putGlobalSettings(KEY_CONTENT_PROTECTION_USER_CONSENT, VALUE_TRUE);
+        boolean secondActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(secondActual).isFalse();
+        verify(mMockDevicePolicyManagerInternal, times(2)).isUserOrganizationManaged(TEST_USER_ID);
+
+        notifyContentObserver(manager, URI_CONTENT_PROTECTION_USER_CONSENT);
+        boolean thirdActual = manager.isConsentGranted(TEST_USER_ID);
+        assertThat(thirdActual).isTrue();
+        verify(mMockDevicePolicyManagerInternal, times(3)).isUserOrganizationManaged(TEST_USER_ID);
+
+        verifyZeroInteractions(mMockDevicePolicyCache);
+    }
+
+    private void putGlobalSettings(String key, int value) {
         Settings.Global.putInt(mTestableContentResolver, key, value);
+    }
+
+    private void notifyContentObserver(ContentProtectionConsentManager manager, Uri uri) {
         // Observer has to be called manually, mTestableContentResolver is not propagating
         manager.mContentObserver.onChange(/* selfChange= */ false, uri, TEST_USER_ID);
     }
 
     private ContentProtectionConsentManager createContentProtectionConsentManager(
-            ContentResolver contentResolver) {
-        return new ContentProtectionConsentManager(
-                new Handler(Looper.getMainLooper()),
-                contentResolver,
-                mMockDevicePolicyManagerInternal);
-    }
-
-    private ContentProtectionConsentManager createContentProtectionConsentManager(
             int valuePackageVerifierUserConsent, int valueContentProtectionUserConsent) {
         Settings.Global.putInt(
                 mTestableContentResolver,
@@ -227,6 +430,14 @@
                 mTestableContentResolver,
                 KEY_CONTENT_PROTECTION_USER_CONSENT,
                 valueContentProtectionUserConsent);
-        return createContentProtectionConsentManager(mTestableContentResolver);
+        return new ContentProtectionConsentManager(
+                new Handler(Looper.getMainLooper()),
+                mTestableContentResolver,
+                mMockDevicePolicyCache);
+    }
+
+    private <T> void setupLocalService(Class<T> clazz, T service) {
+        LocalServices.removeServiceForTest(clazz);
+        LocalServices.addService(clazz, service);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
index 076d5ca..44d1161 100644
--- a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
+++ b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
@@ -147,7 +147,7 @@
             final int n = 4;
             StackTraceElement[] stack = Thread.currentThread().getStackTrace();
             if (stack.length < n+1) return "test";
-            return stack[n].getMethodName();
+            return stack[n].getClassName() + "." + stack[n].getMethodName();
         }
     }
 
@@ -318,8 +318,11 @@
     public void testDumpOutput() throws Exception {
         if (!AnrTimer.nativeTimersSupported()) return;
 
+        // The timers in this class are named "class.method".
+        final String timerName = "timer: com.android.server.utils.AnrTimerTest";
+
         String r1 = getDumpOutput();
-        assertThat(r1).doesNotContain("timer:");
+        assertThat(r1).doesNotContain(timerName);
 
         Helper helper = new Helper(2);
         TestArg t1 = new TestArg(1, 1);
@@ -333,14 +336,14 @@
             String r2 = getDumpOutput();
             // There are timers in the list if and only if the feature is enabled.
             if (mEnabled) {
-              assertThat(r2).contains("timer:");
+                assertThat(r2).contains(timerName);
             } else {
-              assertThat(r2).doesNotContain("timer:");
+                assertThat(r2).doesNotContain(timerName);
             }
         }
 
         String r3 = getDumpOutput();
-        assertThat(r3).doesNotContain("timer:");
+        assertThat(r3).doesNotContain(timerName);
     }
 
     /**
diff --git a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java
index e27bb4c..b9ece93 100644
--- a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java
+++ b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java
@@ -40,12 +40,19 @@
 public class StubTransaction extends SurfaceControl.Transaction {
 
     private HashSet<Runnable> mWindowInfosReportedListeners = new HashSet<>();
+    private HashSet<SurfaceControl.TransactionCommittedListener> mTransactionCommittedListeners =
+            new HashSet<>();
 
     @Override
     public void apply() {
         for (Runnable listener : mWindowInfosReportedListeners) {
             listener.run();
         }
+        for (SurfaceControl.TransactionCommittedListener listener
+                : mTransactionCommittedListeners) {
+            listener.onTransactionCommitted();
+        }
+        mTransactionCommittedListeners.clear();
     }
 
     @Override
@@ -239,6 +246,9 @@
     @Override
     public SurfaceControl.Transaction addTransactionCommittedListener(Executor executor,
             SurfaceControl.TransactionCommittedListener listener) {
+        SurfaceControl.TransactionCommittedListener listenerInner =
+                () -> executor.execute(listener::onTransactionCommitted);
+        mTransactionCommittedListeners.add(listenerInner);
         return this;
     }
 
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java
new file mode 100644
index 0000000..038f1db
--- /dev/null
+++ b/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.vibrator;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.util.IndentingPrintWriter;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.vibrator.GroupedAggregatedLogRecords.AggregatedLogRecord;
+import com.android.server.vibrator.GroupedAggregatedLogRecords.SingleLogRecord;
+
+import org.junit.Test;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class GroupedAggregatedLogRecordsTest {
+
+    private static final int AGGREGATION_TIME_LIMIT = 1000;
+    private static final int NO_AGGREGATION_TIME_LIMIT = 0;
+    private static final long PROTO_FIELD_ID = 1;
+    private static final int GROUP_1 = 1;
+    private static final int GROUP_2 = 2;
+    private static final int KEY_1 = 1;
+    private static final int KEY_2 = 2;
+
+    private static final IndentingPrintWriter WRITER = new IndentingPrintWriter(new StringWriter());
+    private static final ProtoOutputStream PROTO_OUTPUT_STREAM = new ProtoOutputStream();
+
+    private final List<TestSingleLogRecord> mTestRecords = new ArrayList<>();
+
+    @Test
+    public void record_noAggregation_keepsIndividualRecords() {
+        int sizeLimit = 10;
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                sizeLimit, NO_AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        for (int i = 0; i < sizeLimit; i++) {
+            assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull();
+        }
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1);
+        assertRecordsInRangeWrittenOnce(0, sizeLimit);
+    }
+
+    @Test
+    public void record_sizeLimit_dropsOldestEntriesForNewOnes() {
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                /* sizeLimit= */ 2, NO_AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        TestSingleLogRecord firstRecord = createRecord(GROUP_1, KEY_1, createTime++);
+        assertThat(records.add(firstRecord)).isNull();
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull();
+
+        // Adding third record drops first record
+        AggregatedLogRecord<TestSingleLogRecord> droppedRecord =
+                records.add(createRecord(GROUP_1, KEY_1, createTime++));
+        assertThat(droppedRecord).isNotNull();
+        assertThat(droppedRecord.getLatest()).isEqualTo(firstRecord);
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1);
+        assertRecordsInRangeNotWritten(0, 1);  // First record not written
+        assertRecordsInRangeWrittenOnce(1, 3); // All newest records written
+    }
+
+    @Test
+    public void record_timeAggregation_aggregatesCloseRecordAndPrintsOnlyFirstAndLast() {
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        // No record dropped, all aggregated in a single entry
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime))).isNull();
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime + 1))).isNull();
+        assertThat(records.add(createRecord(GROUP_1, KEY_1,
+                createTime + AGGREGATION_TIME_LIMIT - 2))).isNull();
+        assertThat(records.add(createRecord(GROUP_1, KEY_1,
+                createTime + AGGREGATION_TIME_LIMIT - 1))).isNull();
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1);
+        assertRecordsInRangeWrittenOnce(0, 1); // Writes first record
+        assertRecordsInRangeNotWritten(1, 3);  // Skips aggregated records in between
+        assertRecordsInRangeWrittenOnce(3, 4); // Writes last record
+    }
+
+    @Test
+    public void record_differentGroups_recordsKeptSeparate() {
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        // No record dropped, all kept in separate aggregated lists
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull();
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull();
+        assertThat(records.add(createRecord(GROUP_2, KEY_2, createTime++))).isNull();
+        assertThat(records.add(createRecord(GROUP_2, KEY_2, createTime++))).isNull();
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1, GROUP_2);
+        assertRecordsInRangeWrittenOnce(0, 4);
+    }
+
+    @Test
+    public void record_sameGroupDifferentAggregationKeys_recordsNotAggregated() {
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull();
+
+        // Second record on same group with different key not aggregated, drops first record
+        AggregatedLogRecord<TestSingleLogRecord> droppedRecord =
+                records.add(createRecord(GROUP_1, KEY_2, createTime++));
+        assertThat(droppedRecord).isNotNull();
+        assertThat(droppedRecord.getLatest()).isEqualTo(mTestRecords.getFirst());
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1);
+        assertRecordsInRangeNotWritten(0, 1);  // Skips first record that was dropped
+        assertRecordsInRangeWrittenOnce(1, 2); // Writes last record
+    }
+
+    @Test
+    public void record_sameGroupAndAggregationKeysDistantTimes_recordsNotAggregated() {
+        long createTime = 100;
+        TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords(
+                /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID);
+
+        assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime))).isNull();
+
+        // Second record after aggregation time limit not aggregated, drops first record
+        AggregatedLogRecord<TestSingleLogRecord> droppedRecord =
+                records.add(createRecord(GROUP_1, KEY_1, createTime + AGGREGATION_TIME_LIMIT));
+        assertThat(droppedRecord).isNotNull();
+        assertThat(droppedRecord.getLatest()).isEqualTo(mTestRecords.getFirst());
+
+        dumpRecords(records);
+        assertGroupHeadersWrittenOnce(records, GROUP_1);
+        assertRecordsInRangeNotWritten(0, 1);  // Skips first record that was dropped
+        assertRecordsInRangeWrittenOnce(1, 2); // Writes last record
+    }
+
+    private TestSingleLogRecord createRecord(int groupKey, int aggregateKey, long createTime) {
+        TestSingleLogRecord record = new TestSingleLogRecord(groupKey, aggregateKey, createTime);
+        mTestRecords.add(record);
+        return record;
+    }
+
+    private void dumpRecords(TestGroupedAggregatedLogRecords records) {
+        records.dump(WRITER);
+        records.dump(PROTO_OUTPUT_STREAM);
+    }
+
+    private void assertGroupHeadersWrittenOnce(TestGroupedAggregatedLogRecords records,
+            int... groupKeys) {
+        assertThat(records.dumpGroupKeys).containsExactlyElementsIn(
+                Arrays.stream(groupKeys).boxed().toList());
+    }
+
+    private void assertRecordsInRangeWrittenOnce(int startIndexInclusive, int endIndexExclusive) {
+        for (int i = startIndexInclusive; i < endIndexExclusive; i++) {
+            assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpTextCount)
+                    .isEqualTo(1);
+            assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpProtoFieldIds)
+                    .containsExactly(PROTO_FIELD_ID);
+        }
+    }
+
+    private void assertRecordsInRangeNotWritten(int startIndexInclusive, int endIndexExclusive) {
+        for (int i = startIndexInclusive; i < endIndexExclusive; i++) {
+            assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpTextCount)
+                    .isEqualTo(0);
+            assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpProtoFieldIds)
+                    .isEmpty();
+        }
+    }
+
+    private static final class TestGroupedAggregatedLogRecords
+            extends GroupedAggregatedLogRecords<TestSingleLogRecord> {
+
+        public final List<Integer> dumpGroupKeys = new ArrayList<>();
+
+        private final long mProtoFieldId;
+
+        TestGroupedAggregatedLogRecords(int sizeLimit, int aggregationTimeLimitMs,
+                long protoFieldId) {
+            super(sizeLimit, aggregationTimeLimitMs);
+            mProtoFieldId = protoFieldId;
+        }
+
+        @Override
+        void dumpGroupHeader(IndentingPrintWriter pw, int groupKey) {
+            dumpGroupKeys.add(groupKey);
+        }
+
+        @Override
+        long findGroupKeyProtoFieldId(int groupKey) {
+            return mProtoFieldId;
+        }
+    }
+
+    private static final class TestSingleLogRecord implements SingleLogRecord {
+        public final List<Long> dumpProtoFieldIds = new ArrayList<>();
+        public int dumpTextCount = 0;
+
+        private final int mGroupKey;
+        private final int mAggregateKey;
+        private final long mCreateTime;
+
+        TestSingleLogRecord(int groupKey, int aggregateKey, long createTime) {
+            mGroupKey = groupKey;
+            mAggregateKey = aggregateKey;
+            mCreateTime = createTime;
+        }
+
+        @Override
+        public int getGroupKey() {
+            return mGroupKey;
+        }
+
+        @Override
+        public long getCreateUptimeMs() {
+            return mCreateTime;
+        }
+
+        @Override
+        public boolean mayAggregate(SingleLogRecord record) {
+            if (record instanceof TestSingleLogRecord param) {
+                return mAggregateKey == param.mAggregateKey;
+            }
+            return false;
+        }
+
+        @Override
+        public void dump(IndentingPrintWriter pw) {
+            dumpTextCount++;
+        }
+
+        @Override
+        public void dump(ProtoOutputStream proto, long fieldId) {
+            dumpProtoFieldIds.add(fieldId);
+        }
+    }
+}
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
index 3d0dca0..e3d4596 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
@@ -17,9 +17,11 @@
 package com.android.server.vibrator;
 
 import static android.os.VibrationAttributes.CATEGORY_KEYBOARD;
+import static android.os.VibrationAttributes.CATEGORY_UNKNOWN;
 import static android.os.VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
 import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
 import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE;
+import static android.os.VibrationAttributes.USAGE_TOUCH;
 import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
 import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK;
 import static android.os.VibrationEffect.EFFECT_CLICK;
@@ -285,7 +287,8 @@
         HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
 
         VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false);
+                SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false,
+                false /* fromIme*/);
 
         assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isFalse();
     }
@@ -295,7 +298,7 @@
         HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
 
         VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true);
+                SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true, false /* fromIme*/);
 
         assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isTrue();
     }
@@ -307,7 +310,7 @@
 
         for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
             assertWithMessage("Expected FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
                    .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isTrue();
         }
@@ -320,40 +323,59 @@
 
         for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
             assertWithMessage("Expected no FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
                    .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isFalse();
         }
     }
 
     @Test
-    public void testVibrationAttribute_keyboardCategoryOff_notUseKeyboardCategory() {
+    public void testVibrationAttribute_keyboardCategoryOff_isIme_notUseKeyboardCategory() {
         mSetFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
         HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
 
         for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+            assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
+                    .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
             assertWithMessage("Expected no CATEGORY_KEYBOARD for effect " + effectId)
-                    .that(attrs.getCategory()).isEqualTo(0);
+                    .that(attrs.getCategory()).isEqualTo(CATEGORY_UNKNOWN);
         }
     }
 
     @Test
-    public void testVibrationAttribute_keyboardCategoryOn_useKeyboardCategory() {
+    public void testVibrationAttribute_keyboardCategoryOn_notIme_notUseKeyboardCategory() {
         mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
         HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
 
         for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+            assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
+                    .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
+            assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId)
+                    .that(attrs.getCategory()).isEqualTo(CATEGORY_UNKNOWN);
+        }
+    }
+
+    @Test
+    public void testVibrationAttribute_keyboardCategoryOn_isIme_useKeyboardCategory() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
+        HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
+
+        for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
+            VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
+                    effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
+            assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
+                    .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
             assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId)
                     .that(attrs.getCategory()).isEqualTo(CATEGORY_KEYBOARD);
         }
     }
 
     @Test
-    public void testVibrationAttribute_noFixAmplitude_keyboardCategoryOn_noBypassIntensityScale() {
+    public void testVibrationAttribute_noFixAmplitude_notBypassIntensityScale() {
         mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
         mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK);
         mockKeyboardVibrationFixedAmplitude(-1);
@@ -361,7 +383,7 @@
 
         for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
             assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
                     + effectId)
                     .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse();
@@ -369,7 +391,7 @@
     }
 
     @Test
-    public void testVibrationAttribute_fixAmplitude_keyboardCategoryOn_bypassIntensityScale() {
+    public void testVibrationAttribute_notIme_notBypassIntensityScale() {
         mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
         mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK);
         mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE);
@@ -377,7 +399,23 @@
 
         for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
             VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
-                    effectId, /* bypassVibrationIntensitySetting= */ false);
+                    effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/);
+            assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
+                    + effectId)
+                    .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse();
+        }
+    }
+
+    @Test
+    public void testVibrationAttribute_fixAmplitude_isIme_bypassIntensityScale() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED);
+        mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK);
+        mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE);
+        HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
+
+        for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
+            VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
+                    effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/);
             assertWithMessage("Expected FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect "
                     + effectId)
                     .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isTrue();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java
index 3e59878..b264435 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java
@@ -117,32 +117,32 @@
     }
 
     @Test
-    public void testGetExternalVibrationScale() {
+    public void testGetScaleLevel() {
         setDefaultIntensity(USAGE_TOUCH, Vibrator.VIBRATION_INTENSITY_LOW);
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_HIGH);
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
 
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_MEDIUM);
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_HIGH,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
 
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_LOW);
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_NONE,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
 
         setDefaultIntensity(USAGE_TOUCH, VIBRATION_INTENSITY_MEDIUM);
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_LOW,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
 
         setDefaultIntensity(USAGE_TOUCH, VIBRATION_INTENSITY_HIGH);
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
 
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
         // Vibration setting being bypassed will use default setting and not scale.
         assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_NONE,
-                mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH));
+                mVibrationScaler.getScaleLevel(USAGE_TOUCH));
     }
 
     @Test
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
index 0d5bf95..3799abc 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
@@ -38,10 +38,10 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.util.SparseArray;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.internal.util.ArrayUtils;
@@ -86,20 +86,20 @@
                 ApplicationProvider.getApplicationContext(), new Handler(testLooper.getLooper()));
 
         mFakeVibratorController = new FakeVibratorController(mTestLooper.getLooper());
-        mVibratorControlService = new VibratorControlService(new VibratorControllerHolder(),
+        mVibratorControlService = new VibratorControlService(
+                InstrumentationRegistry.getContext(), new VibratorControllerHolder(),
                 mMockVibrationScaler, mVibrationSettings, mLock);
     }
 
     @Test
-    public void testRegisterVibratorController() throws RemoteException {
+    public void testRegisterVibratorController() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
 
         assertThat(mFakeVibratorController.isLinkedToDeath).isTrue();
     }
 
     @Test
-    public void testUnregisterVibratorController_providingTheRegisteredController_performsRequest()
-            throws RemoteException {
+    public void testUnregisterVibratorController_providingRegisteredController_performsRequest() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         mVibratorControlService.unregisterVibratorController(mFakeVibratorController);
 
@@ -108,8 +108,7 @@
     }
 
     @Test
-    public void testUnregisterVibratorController_providingAnInvalidController_ignoresRequest()
-            throws RemoteException {
+    public void testUnregisterVibratorController_providingAnInvalidController_ignoresRequest() {
         FakeVibratorController controller1 = new FakeVibratorController(mTestLooper.getLooper());
         FakeVibratorController controller2 = new FakeVibratorController(mTestLooper.getLooper());
         mVibratorControlService.registerVibratorController(controller1);
@@ -120,8 +119,7 @@
     }
 
     @Test
-    public void testOnRequestVibrationParamsComplete_cachesAdaptiveHapticsScalesCorrectly()
-            throws RemoteException {
+    public void testOnRequestVibrationParamsComplete_cachesAdaptiveHapticsScalesCorrectly() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         int timeoutInMillis = 10;
         CompletableFuture<Void> future =
@@ -148,8 +146,7 @@
     }
 
     @Test
-    public void testOnRequestVibrationParamsComplete_withIncorrectToken_ignoresRequest()
-            throws RemoteException, InterruptedException {
+    public void testOnRequestVibrationParamsComplete_withIncorrectToken_ignoresRequest() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         int timeoutInMillis = 10;
         CompletableFuture<Void> unusedFuture =
@@ -167,8 +164,7 @@
     }
 
     @Test
-    public void testSetVibrationParams_cachesAdaptiveHapticsScalesCorrectly()
-            throws RemoteException {
+    public void testSetVibrationParams_cachesAdaptiveHapticsScalesCorrectly() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         SparseArray<Float> vibrationScales = new SparseArray<>();
         vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f);
@@ -187,8 +183,7 @@
     }
 
     @Test
-    public void testSetVibrationParams_withUnregisteredController_ignoresRequest()
-            throws RemoteException {
+    public void testSetVibrationParams_withUnregisteredController_ignoresRequest() {
         SparseArray<Float> vibrationScales = new SparseArray<>();
         vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f);
         vibrationScales.put(ScaleParam.TYPE_NOTIFICATION, 0.4f);
@@ -201,8 +196,7 @@
     }
 
     @Test
-    public void testClearVibrationParams_clearsCachedAdaptiveHapticsScales()
-            throws RemoteException {
+    public void testClearVibrationParams_clearsCachedAdaptiveHapticsScales() {
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         int types = buildVibrationTypesMask(ScaleParam.TYPE_ALARM, ScaleParam.TYPE_NOTIFICATION);
 
@@ -216,8 +210,7 @@
     }
 
     @Test
-    public void testClearVibrationParams_withUnregisteredController_ignoresRequest()
-            throws RemoteException {
+    public void testClearVibrationParams_withUnregisteredController_ignoresRequest() {
         mVibratorControlService.clearVibrationParams(ScaleParam.TYPE_ALARM,
                 mFakeVibratorController);
 
@@ -225,8 +218,7 @@
     }
 
     @Test
-    public void testRequestVibrationParams_createsFutureRequestProperly()
-            throws RemoteException {
+    public void testRequestVibrationParams_createsFutureRequestProperly() {
         int timeoutInMillis = 10;
         mVibratorControlService.registerVibratorController(mFakeVibratorController);
         CompletableFuture<Void> future =
@@ -243,8 +235,7 @@
     }
 
     @Test
-    public void testShouldRequestVibrationParams_returnsTrueForVibrationsThatShouldRequestParams()
-            throws RemoteException {
+    public void testShouldRequestVibrationParams_returnsTrueForVibrationsThatShouldRequestParams() {
         int[] vibrations =
                 new int[]{USAGE_ALARM, USAGE_RINGTONE, USAGE_MEDIA, USAGE_TOUCH, USAGE_NOTIFICATION,
                         USAGE_HARDWARE_FEEDBACK, USAGE_UNKNOWN, USAGE_COMMUNICATION_REQUEST};
@@ -258,8 +249,7 @@
     }
 
     @Test
-    public void testShouldRequestVibrationParams_unregisteredVibratorController_returnsFalse()
-            throws RemoteException {
+    public void testShouldRequestVibrationParams_unregisteredVibratorController_returnsFalse() {
         int[] vibrations =
                 new int[]{USAGE_ALARM, USAGE_RINGTONE, USAGE_MEDIA, USAGE_TOUCH, USAGE_NOTIFICATION,
                         USAGE_HARDWARE_FEEDBACK, USAGE_UNKNOWN, USAGE_COMMUNICATION_REQUEST};
@@ -269,7 +259,7 @@
         }
     }
 
-    private int buildVibrationTypesMask(int... types) {
+    private static int buildVibrationTypesMask(int... types) {
         int typesMask = 0;
         for (int type : types) {
             typesMask |= type;
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index d2ad61f..1ea90f5 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -2526,7 +2526,7 @@
                 int constant, boolean always) throws InterruptedException {
         HalVibration vib =
                 service.performHapticFeedbackInternal(UID, Context.DEVICE_ID_DEFAULT, PACKAGE_NAME,
-                        constant, always, "some reason", service);
+                        constant, always, "some reason", service, false /* fromIme */);
         if (vib != null) {
             vib.waitForEnd();
         }
diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java
index 2a010f0..0cd88ef 100644
--- a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java
+++ b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java
@@ -60,11 +60,7 @@
         requestTimeoutInMillis = timeoutInMillis;
         mHandler.post(() -> {
             if (mVibratorControlService != null) {
-                try {
-                    mVibratorControlService.onRequestVibrationParamsComplete(token, mRequestResult);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
+                mVibratorControlService.onRequestVibrationParamsComplete(token, mRequestResult);
             }
         });
     }
diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp
index 8a79fe4..8c70851 100644
--- a/services/tests/voiceinteractiontests/Android.bp
+++ b/services/tests/voiceinteractiontests/Android.bp
@@ -45,6 +45,7 @@
         "servicestests-utils-mockito-extended",
         "truth",
         "frameworks-base-testutils",
+        "androidx.test.rules",
     ],
 
     libs: [
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java
index 35170b3..a9c517d 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java
@@ -16,19 +16,20 @@
 
 package com.android.server.soundtrigger;
 
+import android.hardware.soundtrigger.SoundTrigger;
 import android.hardware.soundtrigger.SoundTrigger.ConfidenceLevel;
 import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
-import android.hardware.soundtrigger.SoundTrigger;
 import android.media.AudioFormat;
+import android.os.Binder;
 import android.os.Parcel;
 import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.os.Binder;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.SmallTest;
 
 import java.util.Arrays;
 import java.util.Locale;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 67c528c..09e7b91 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -527,7 +527,8 @@
 
         // The configuration change is still sent to the activity, even if it doesn't relaunch.
         final ActivityConfigurationChangeItem expected =
-                ActivityConfigurationChangeItem.obtain(activity.token, newConfig);
+                ActivityConfigurationChangeItem.obtain(activity.token, newConfig,
+                        activity.getActivityWindowInfo());
         verify(mClientLifecycleManager).scheduleTransactionItem(
                 eq(activity.app.getThread()), eq(expected));
     }
@@ -599,7 +600,8 @@
         final Configuration currentConfig = activity.getConfiguration();
         assertEquals(expectedOrientation, currentConfig.orientation);
         final ActivityConfigurationChangeItem expected =
-                ActivityConfigurationChangeItem.obtain(activity.token, currentConfig);
+                ActivityConfigurationChangeItem.obtain(activity.token, currentConfig,
+                        activity.getActivityWindowInfo());
         verify(mClientLifecycleManager).scheduleTransactionItem(activity.app.getThread(), expected);
         verify(displayRotation).onSetRequestedOrientation();
     }
@@ -818,7 +820,7 @@
 
             final ActivityConfigurationChangeItem expected =
                     ActivityConfigurationChangeItem.obtain(activity.token,
-                            activity.getConfiguration());
+                            activity.getConfiguration(), activity.getActivityWindowInfo());
             verify(mClientLifecycleManager).scheduleTransactionItem(
                     activity.app.getThread(), expected);
         } finally {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0c1fbf3..1a1fe95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -94,6 +94,7 @@
     public void setUp() throws Exception {
         assumeFalse(WindowManagerService.sEnableShellTransitions);
         mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
+        mWm.mAnimator.ready();
     }
 
     @Test
@@ -855,7 +856,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation run by the remote handler.
         assertTrue(remoteAnimationRunner.isAnimationStarted());
@@ -886,7 +887,7 @@
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity,
                 null /* changingTaskFragment */);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation is not run by the remote handler because the activity is filling the Task.
         assertFalse(remoteAnimationRunner.isAnimationStarted());
@@ -921,7 +922,7 @@
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity,
                 null /* changingTaskFragment */);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation run by the remote handler.
         assertTrue(remoteAnimationRunner.isAnimationStarted());
@@ -946,7 +947,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation run by the remote handler.
         assertTrue(remoteAnimationRunner.isAnimationStarted());
@@ -973,7 +974,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment1);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation run by the remote handler.
         assertTrue(remoteAnimationRunner.isAnimationStarted());
@@ -997,7 +998,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation not run by the remote handler.
         assertFalse(remoteAnimationRunner.isAnimationStarted());
@@ -1024,7 +1025,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation should not run by the remote handler when there are non-embedded activities of
         // different UID.
@@ -1051,7 +1052,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // Animation should not run by the remote handler when there is wallpaper in the transition.
         assertFalse(remoteAnimationRunner.isAnimationStarted());
@@ -1085,7 +1086,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(activity1, null /* closingActivity */, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // The animation will be animated remotely by client and all activities are input disabled
         // for untrusted animation.
@@ -1136,7 +1137,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // The animation will be animated remotely by client and all activities are input disabled
         // for untrusted animation.
@@ -1178,7 +1179,7 @@
 
         // Prepare and start transition.
         prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
 
         // The animation will be animated remotely by client, but input should not be dropped for
         // fully trusted.
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 2085d61..1f15ec3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -371,6 +371,7 @@
         mDisplayContent.getInsetsPolicy().updateBarControlTarget(app);
         mDisplayContent.getInsetsPolicy().showTransient(statusBars(),
                 true /* isGestureOnSystemBar */);
+        mWm.mAnimator.ready();
         waitUntilWindowAnimatorIdle();
 
         assertTrue(mDisplayContent.getInsetsPolicy().isTransient(statusBars()));
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 11d9629..a163801 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -43,7 +43,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -113,6 +112,7 @@
         runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0);
         mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter,
                 mHandler, false /*isActivityEmbedding*/);
+        mWm.mAnimator.ready();
     }
 
     private WindowState createAppOverlayWindow() {
@@ -136,7 +136,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -168,7 +168,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -290,7 +290,7 @@
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
         final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                 ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
         final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -336,7 +336,7 @@
         task.applyAnimationUnchecked(null /* lp */, true /* enter */, TRANSIT_OLD_TASK_OPEN,
                 false /* isVoiceInteraction */, null /* sources */);
         mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
         final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                 ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
         try {
@@ -363,7 +363,7 @@
             ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash,
                     mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -417,7 +417,7 @@
             ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash,
                     mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -471,7 +471,7 @@
             ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash,
                     mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -526,7 +526,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -559,7 +559,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -595,7 +595,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -645,7 +645,7 @@
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
             final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
                     ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
             final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
@@ -782,7 +782,7 @@
 
             mDisplayContent.applySurfaceChangesTransaction();
             mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
-            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            waitUntilWindowAnimatorIdle();
 
             verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
                     any(), any(), any(), any());
@@ -810,7 +810,7 @@
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(transit);
-        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        waitUntilWindowAnimatorIdle();
         return adapter;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index a8f6fe8..7ab093d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -546,7 +546,7 @@
         // This makes sure all previous messages in the handler are fully processed vs. just popping
         // them from the message queue.
         final AtomicBoolean currentMessagesProcessed = new AtomicBoolean(false);
-        wm.mAnimator.getChoreographer().postFrameCallback(time -> {
+        wm.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
             synchronized (currentMessagesProcessed) {
                 currentMessagesProcessed.set(true);
                 currentMessagesProcessed.notifyAll();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 7551b165..1233686 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -265,7 +265,7 @@
 
     @Override
     public boolean performHapticFeedback(int uid, String packageName, int effectId,
-            boolean always, String reason) {
+            boolean always, String reason, boolean fromIme) {
         return false;
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 0f2c62d..2da352d 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -48,6 +48,7 @@
 import android.hardware.usb.UsbPortStatus;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -65,6 +66,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.FgThread;
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
@@ -151,6 +153,7 @@
     private final UsbPermissionManager mPermissionManager;
 
     static final int PACKAGE_MONITOR_OPERATION_ID = 1;
+    static final int STRONG_AUTH_OPERATION_ID = 2;
     /**
      * The user id of the current user. There might be several profiles (with separate user ids)
      * per user.
@@ -272,6 +275,10 @@
         if (android.hardware.usb.flags.Flags.enableUsbDataSignalStaking()) {
             new PackageUninstallMonitor()
                     .register(mContext, UserHandle.ALL, BackgroundThread.getHandler());
+
+            new LockPatternUtils(mContext)
+                    .registerStrongAuthTracker(new StrongAuthTracker(mContext,
+                            BackgroundThread.getHandler().getLooper()));
         }
     }
 
@@ -1408,4 +1415,33 @@
             }
         }
     }
+
+    /**
+     * Implements a callback within StrongAuthTracker to disable USB data signaling
+     * when the device enters lockdown mode. This likely involves updating a state
+     * that controls USB data behavior.
+     */
+    private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+        private boolean mLockdownModeStatus;
+
+        StrongAuthTracker(Context context, Looper looper) {
+            super(context, looper);
+        }
+
+        @Override
+        public synchronized void onStrongAuthRequiredChanged(int userId) {
+
+            boolean lockDownTriggeredByUser = (getStrongAuthForUser(userId)
+                    & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0;
+            //if it goes into the same lockdown status, no change is needed
+            if (mLockdownModeStatus == lockDownTriggeredByUser) {
+                return;
+            }
+            mLockdownModeStatus = lockDownTriggeredByUser;
+            for (UsbPort port: mPortManager.getPorts()) {
+                enableUsbData(port.getId(), !lockDownTriggeredByUser, STRONG_AUTH_OPERATION_ID,
+                        new IUsbOperationInternal.Default());
+            }
+        }
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index b3db2de..862aff9 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -31,12 +31,11 @@
 import static android.provider.Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY;
 import static android.provider.Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT;
 
-import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type;
-import static com.android.server.utils.EventLogger.Event.ALOGW;
-
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.soundtrigger.DeviceStateHandler.DeviceStateListener;
 import static com.android.server.soundtrigger.DeviceStateHandler.SoundTriggerDeviceState;
+import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type;
+import static com.android.server.utils.EventLogger.Event.ALOGW;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -94,8 +93,8 @@
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.SparseArray;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.ISoundTriggerService;
@@ -105,19 +104,17 @@
 import com.android.server.SystemService;
 import com.android.server.soundtrigger.SoundTriggerEvent.ServiceEvent;
 import com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent;
-import com.android.server.utils.EventLogger.Event;
 import com.android.server.utils.EventLogger;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.function.Consumer;
-import java.util.List;
-import java.util.Set;
 import java.util.Deque;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
@@ -126,6 +123,7 @@
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 /**
@@ -257,6 +255,11 @@
         publishLocalService(SoundTriggerInternal.class, mLocalSoundTriggerService);
     }
 
+    private boolean hasCalling() {
+        return mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY_CALLING);
+    }
+
     @Override
     public void onBootPhase(int phase) {
         Slog.d(TAG, "onBootPhase: " + phase + " : " + isSafeMode());
@@ -282,11 +285,13 @@
             // Do so after registering the listener so we ensure that we don't drop any events
             mDeviceStateHandler.onPowerModeChanged(powerManager.getSoundTriggerPowerSaveMode());
 
-            // PhoneCallStateHandler initializes the original call state
-            mPhoneCallStateHandler = new PhoneCallStateHandler(
-                      mContext.getSystemService(SubscriptionManager.class),
-                      mContext.getSystemService(TelephonyManager.class),
-                      mDeviceStateHandler);
+            if (hasCalling()) {
+                // PhoneCallStateHandler initializes the original call state
+                mPhoneCallStateHandler = new PhoneCallStateHandler(
+                        mContext.getSystemService(SubscriptionManager.class),
+                        mContext.getSystemService(TelephonyManager.class),
+                        mDeviceStateHandler);
+            }
         }
         mMiddlewareService = ISoundTriggerMiddlewareService.Stub.asInterface(
                 ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index aef7158..1e1dd00 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -181,10 +181,8 @@
                 LocalServices.getService(ActivityManagerInternal.class));
         mAtmInternal = Objects.requireNonNull(
                 LocalServices.getService(ActivityTaskManagerInternal.class));
-        mWmInternal = Objects.requireNonNull(
-                LocalServices.getService(WindowManagerInternal.class));
-        mDpmInternal = Objects.requireNonNull(
-                LocalServices.getService(DevicePolicyManagerInternal.class));
+        mWmInternal = LocalServices.getService(WindowManagerInternal.class);
+        mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
         LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService(
                 LegacyPermissionManagerInternal.class);
         permissionManagerInternal.setVoiceInteractionPackagesProvider(
@@ -2750,11 +2748,17 @@
                 if (isAssistDataAllowed) {
                     visiblePackageNames.add(record.getComponentName().getPackageName());
                 }
-                if (mDpmInternal.isUserOrganizationManaged(record.getUserId())) {
+                if (mDpmInternal != null
+                        && mDpmInternal.isUserOrganizationManaged(record.getUserId())) {
                     isManagedProfileVisible = true;
                 }
             }
-            final ScreenCapture.ScreenshotHardwareBuffer shb = mWmInternal.takeAssistScreenshot();
+            final ScreenCapture.ScreenshotHardwareBuffer shb;
+            if (mWmInternal != null) {
+                shb = mWmInternal.takeAssistScreenshot();
+            } else {
+                shb = null;
+            }
             final Bitmap bm = shb != null ? shb.asBitmap() : null;
             // Now that everything is fetched, putting it in the launchIntent.
             if (bm != null) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 626a2e5..88acbab 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8435,7 +8435,7 @@
      * In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of this
      * API must also be listed in the device configuration as an authorized app in
      * {@code packages/services/Telephony/res/values/config.xml} under the
-     * {@code config_number_verification_package_name} key.
+     * {@code platform_number_verification_package} key.
      *
      * @hide
      * @param range The range of phone numbers the caller expects a phone call from.
@@ -15023,7 +15023,7 @@
     @FlaggedApi(android.permission.flags.Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED)
     @NonNull
     @SystemApi
-    public String getEmergencyAssistancePackage() {
+    public String getEmergencyAssistancePackageName() {
         if (!isEmergencyAssistanceEnabled() || !isVoiceCapable()) {
             throw new IllegalStateException("isEmergencyAssistanceEnabled() is false or device"
                 + " not voice capable.");
@@ -18535,7 +18535,7 @@
      * @hide
      */
     @SystemApi
-    @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES)
+    @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_GET_LAST_KNOWN_CELL_IDENTITY)
     @RequiresPermission(allOf = {Manifest.permission.ACCESS_FINE_LOCATION,
             Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID})
     public @Nullable CellIdentity getLastKnownCellIdentity() {
diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
index d6e2861..cc0255d 100644
--- a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
+++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
@@ -15,6 +15,14 @@
  */
 package android.gameperformance;
 
+import android.annotation.NonNull;
+import android.app.Activity;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import androidx.test.filters.SmallTest;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -22,18 +30,6 @@
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
-import android.annotation.NonNull;
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Trace;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
 public class GamePerformanceTest extends
         ActivityInstrumentationTestCase2<GamePerformanceActivity> {
     private final static String TAG = "GamePerformanceTest";
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
index b9f1738..a963890 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
@@ -37,7 +37,7 @@
 public class PerfettoDataSourceTest {
     @Before
     public void before() {
-        assumeTrue(android.tracing.Flags.perfettoProtolog());
+        assumeTrue(android.tracing.Flags.perfettoProtologTracing());
     }
 
     @Test
diff --git a/tests/SurfaceComposition/Android.bp b/tests/SurfaceComposition/Android.bp
index f5aba8f5..a02662f 100644
--- a/tests/SurfaceComposition/Android.bp
+++ b/tests/SurfaceComposition/Android.bp
@@ -32,7 +32,10 @@
         enabled: false,
     },
     srcs: ["src/**/*.java"],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "androidx.test.rules",
+    ],
     libs: [
         "android.test.runner.stubs",
         "android.test.base.stubs",
diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
index 261ea2e..f82585c 100644
--- a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
+++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
@@ -22,9 +22,10 @@
 import android.surfacecomposition.SurfaceCompositionMeasuringActivity.AllocationScore;
 import android.surfacecomposition.SurfaceCompositionMeasuringActivity.CompositorScore;
 import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import androidx.test.filters.SmallTest;
+
 public class SurfaceCompositionTest extends
         ActivityInstrumentationTestCase2<SurfaceCompositionMeasuringActivity> {
     private final static String TAG = "SurfaceCompositionTest";
diff --git a/tests/permission/Android.bp b/tests/permission/Android.bp
index d06809b..b02f410 100644
--- a/tests/permission/Android.bp
+++ b/tests/permission/Android.bp
@@ -20,6 +20,7 @@
         "androidx.test.runner",
         "junit",
         "platform-test-annotations",
+        "androidx.test.rules",
     ],
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index 5fb23b0a..99ca9c08 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -21,7 +21,8 @@
 import android.app.IActivityManager;
 import android.content.res.Configuration;
 import android.os.RemoteException;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import junit.framework.TestCase;
 
diff --git a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
index 299d8d0..0c9d447 100644
--- a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
@@ -19,7 +19,8 @@
 import android.app.PackageInstallObserver;
 import android.content.pm.PackageManager;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 /**
  * Verify PackageManager api's that require specific permissions.
diff --git a/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java
index 4172743..2fa0b21 100644
--- a/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java
@@ -18,7 +18,8 @@
 
 import android.telephony.SmsManager;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import java.util.ArrayList;
 
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 330bc84..e67fd67 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -23,9 +23,10 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.IWindowManager;
 
+import androidx.test.filters.SmallTest;
+
 import junit.framework.TestCase;
 
 /**
diff --git a/tests/utils/testutils/tests/Android.bp b/tests/utils/testutils/tests/Android.bp
index b901b18..8104280 100644
--- a/tests/utils/testutils/tests/Android.bp
+++ b/tests/utils/testutils/tests/Android.bp
@@ -31,6 +31,7 @@
         "androidx.test.runner",
         "mockito-target-minus-junit4",
         "frameworks-base-testutils",
+        "androidx.test.rules",
     ],
 
     libs: [
diff --git a/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java b/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java
index c72e20c..6205b98 100644
--- a/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java
+++ b/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java
@@ -28,7 +28,8 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt
index 83e09bf..fd7474b 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt
@@ -20,7 +20,7 @@
 
 /**
  * Filter to apply a policy to classes extending or implementing a class,
- * either directly or indirectly. (with a breadth first search.)
+ * either directly or indirectly.
  *
  * The policy won't apply to the super class itself.
  */
@@ -42,7 +42,7 @@
     }
 
     /**
-     * Find a policy for a class with a breadth-first search.
+     * Find a policy for a class.
      */
     private fun findPolicyForClass(className: String): FilterPolicyWithReason? {
         val cn = classes.findClass(className) ?: return null
diff --git a/tools/protologtool/src/com/android/protolog/tool/Constants.kt b/tools/protologtool/src/com/android/protolog/tool/Constants.kt
index aa3e00f..4a93de9 100644
--- a/tools/protologtool/src/com/android/protolog/tool/Constants.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/Constants.kt
@@ -18,7 +18,7 @@
 
 object Constants {
         const val NAME = "protologtool"
-        const val VERSION = "1.0.0"
+        const val VERSION = "2.0.0"
         const val IS_ENABLED_METHOD = "isEnabled"
         const val ENUM_VALUES_METHOD = "values"
 }