Merge "Move PersistentDataBlock* in server to its namespace" into main
diff --git a/Android.mk b/Android.mk
index d9e202c..e2c1ed8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -69,9 +69,6 @@
 .PHONY: framework-doc-stubs
 framework-doc-stubs: $(SDK_METADATA)
 
-# Run this for checkbuild
-checkbuild: doc-comment-check-docs
-
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/OWNERS b/OWNERS
index 4e5c7d8..023bdef 100644
--- a/OWNERS
+++ b/OWNERS
@@ -34,3 +34,6 @@
 
 per-file ZYGOTE_OWNERS = file:/ZYGOTE_OWNERS
 per-file SQLITE_OWNERS = file:/SQLITE_OWNERS
+
+per-file *ravenwood* = file:ravenwood/OWNERS
+per-file *Ravenwood* = file:ravenwood/OWNERS
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index e636f60..dfa9183 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -1327,13 +1327,13 @@
     private void handleOpTimeoutLocked() {
         switch (mVerb) {
             case VERB_BINDING:
-                onSlowAppResponseLocked(/* reschedule */ false, /* updateStopReasons */ true,
+                // The system may have been too busy. Don't drop the job or trigger an ANR.
+                onSlowAppResponseLocked(/* reschedule */ true, /* updateStopReasons */ true,
                         /* texCounterMetricId */
                         "job_scheduler.value_cntr_w_uid_slow_app_response_binding",
                         /* debugReason */ "timed out while binding",
                         /* anrMessage */ "Timed out while trying to bind",
-                        CompatChanges.isChangeEnabled(ANR_PRE_UDC_APIS_ON_SLOW_RESPONSES,
-                            mRunningJob.getUid()));
+                        /* triggerAnr */ false);
                 break;
             case VERB_STARTING:
                 // Client unresponsive - wedged or failed to respond in time. We don't really
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index 0a7bffc..4b4e512 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -1118,6 +1118,7 @@
             }
             boolean needFileMigration = false;
             long nowElapsed = sElapsedRealtimeClock.millis();
+            int numDuplicates = 0;
             synchronized (mLock) {
                 for (File file : files) {
                     final AtomicFile aFile = createJobFile(file);
@@ -1126,6 +1127,16 @@
                         if (jobs != null) {
                             for (int i = 0; i < jobs.size(); i++) {
                                 JobStatus js = jobs.get(i);
+                                final JobStatus existingJob = this.jobSet.get(
+                                        js.getUid(), js.getNamespace(), js.getJobId());
+                                if (existingJob != null) {
+                                    numDuplicates++;
+                                    // Jobs are meant to have unique uid-namespace-jobId
+                                    // combinations, but we've somehow read multiple jobs with the
+                                    // combination. Drop the latter one since keeping both will
+                                    // result in other issues.
+                                    continue;
+                                }
                                 js.prepareLocked();
                                 js.enqueueTime = nowElapsed;
                                 this.jobSet.add(js);
@@ -1174,6 +1185,10 @@
                 migrateJobFilesAsync();
             }
 
+            if (numDuplicates > 0) {
+                Slog.wtf(TAG, "Encountered " + numDuplicates + " duplicate persisted jobs");
+            }
+
             // Log the count immediately after loading from boot.
             mCurrentJobSetSize = numJobs;
             mScheduledJob30MinHighWaterMark = mCurrentJobSetSize;
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index 6461c00..30b4423 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -20,41 +20,6 @@
 // The API doc generation is done by the various droiddoc modules each of which
 // is for different format.
 
-/////////////////////////////////////////////////////////////////////
-// stub source files are generated using metalava
-/////////////////////////////////////////////////////////////////////
-
-framework_docs_only_libs = [
-    "voip-common",
-    "android.test.mock",
-    "android-support-annotations",
-    "android-support-compat",
-    "android-support-core-ui",
-    "android-support-core-utils",
-    "android-support-design",
-    "android-support-dynamic-animation",
-    "android-support-exifinterface",
-    "android-support-fragment",
-    "android-support-media-compat",
-    "android-support-percent",
-    "android-support-transition",
-    "android-support-v7-cardview",
-    "android-support-v7-gridlayout",
-    "android-support-v7-mediarouter",
-    "android-support-v7-palette",
-    "android-support-v7-preference",
-    "android-support-v13",
-    "android-support-v14-preference",
-    "android-support-v17-leanback",
-    "android-support-vectordrawable",
-    "android-support-animatedvectordrawable",
-    "android-support-v7-appcompat",
-    "android-support-v7-recyclerview",
-    "android-support-v8-renderscript",
-    "android-support-multidex",
-    "android-support-multidex-instrumentation",
-]
-
 // These defaults enable doc-stub generation, api lint database generation and sdk value generation.
 stubs_defaults {
     name: "android-non-updatable-doc-stubs-defaults",
@@ -65,7 +30,6 @@
         ":android-test-mock-sources",
         ":android-test-runner-sources",
     ],
-    libs: framework_docs_only_libs,
     create_doc_stubs: true,
     write_sdk_values: true,
 }
@@ -195,7 +159,9 @@
 
 doc_defaults {
     name: "framework-docs-default",
-    libs: framework_docs_only_libs + [
+    sdk_version: "none",
+    system_modules: "none",
+    libs: [
         "stub-annotations",
         "unsupportedappusage",
     ],
@@ -234,20 +200,6 @@
     },
 }
 
-doc_defaults {
-    name: "framework-dokka-docs-default",
-}
-
-droiddoc {
-    name: "doc-comment-check-docs",
-    defaults: ["framework-docs-default"],
-    srcs: [
-        ":framework-doc-stubs",
-    ],
-    args: framework_docs_only_args + " -referenceonly -parsecomments",
-    installable: false,
-}
-
 droiddoc {
     name: "offline-sdk-docs",
     defaults: ["framework-docs-default"],
@@ -301,70 +253,6 @@
 }
 
 droiddoc {
-    name: "online-sdk-docs",
-    defaults: ["framework-docs-default"],
-    srcs: [
-        ":framework-doc-stubs",
-    ],
-    hdf: [
-        "android.whichdoc online",
-        "android.hasSamples true",
-    ],
-    proofread_file: "online-sdk-docs-proofread.txt",
-    args: framework_docs_only_args +
-        " -toroot / -samplegroup Admin " +
-        " -samplegroup Background " +
-        " -samplegroup Connectivity " +
-        " -samplegroup Content " +
-        " -samplegroup Input " +
-        " -samplegroup Media " +
-        " -samplegroup Notification " +
-        " -samplegroup RenderScript " +
-        " -samplegroup Security " +
-        " -samplegroup Sensors " +
-        " -samplegroup System " +
-        " -samplegroup Testing " +
-        " -samplegroup UI " +
-        " -samplegroup Views " +
-        " -samplegroup Wearable -samplesdir development/samples/browseable ",
-}
-
-droiddoc {
-    name: "online-system-api-sdk-docs",
-    defaults: ["framework-docs-default"],
-    srcs: [
-        ":framework-doc-system-stubs",
-    ],
-    hdf: [
-        "android.whichdoc online",
-        "android.hasSamples true",
-    ],
-    proofread_file: "online-system-api-sdk-docs-proofread.txt",
-    args: framework_docs_only_args +
-        " -referenceonly " +
-        " -title \"Android SDK - Including system APIs.\" " +
-        " -hide 101 " +
-        " -hide 104 " +
-        " -hide 108 " +
-        " -toroot / -samplegroup Admin " +
-        " -samplegroup Background " +
-        " -samplegroup Connectivity " +
-        " -samplegroup Content " +
-        " -samplegroup Input " +
-        " -samplegroup Media " +
-        " -samplegroup Notification " +
-        " -samplegroup RenderScript " +
-        " -samplegroup Security " +
-        " -samplegroup Sensors " +
-        " -samplegroup System " +
-        " -samplegroup Testing " +
-        " -samplegroup UI " +
-        " -samplegroup Views " +
-        " -samplegroup Wearable -samplesdir development/samples/browseable ",
-    installable: false,
-}
-
-droiddoc {
     name: "ds-docs-java",
     defaults: ["framework-docs-default"],
     srcs: [
@@ -395,7 +283,6 @@
 
 droiddoc {
     name: "ds-docs-kt",
-    defaults: ["framework-dokka-docs-default"],
     srcs: [
         ":framework-doc-stubs",
     ],
@@ -474,44 +361,3 @@
         " -atLinksNavtree " +
         " -navtreeonly ",
 }
-
-droiddoc {
-    name: "online-sdk-dev-docs",
-    defaults: ["framework-docs-default"],
-    srcs: [
-        ":framework-doc-stubs",
-    ],
-    hdf: [
-        "android.whichdoc online",
-        "android.hasSamples true",
-    ],
-    proofread_file: "online-sdk-dev-docs-proofread.txt",
-    args: framework_docs_only_args +
-        " -toroot / -samplegroup Admin " +
-        " -samplegroup Background " +
-        " -samplegroup Connectivity " +
-        " -samplegroup Content " +
-        " -samplegroup Input " +
-        " -samplegroup Media " +
-        " -samplegroup Notification " +
-        " -samplegroup RenderScript " +
-        " -samplegroup Security " +
-        " -samplegroup Sensors " +
-        " -samplegroup System " +
-        " -samplegroup Testing " +
-        " -samplegroup UI " +
-        " -samplegroup Views " +
-        " -samplegroup Wearable -samplesdir development/samples/browseable ",
-}
-
-droiddoc {
-    name: "hidden-docs",
-    defaults: ["framework-docs-default"],
-    srcs: [
-        ":framework-doc-stubs",
-    ],
-    proofread_file: "hidden-docs-proofread.txt",
-    args: framework_docs_only_args +
-        " -referenceonly " +
-        " -title \"Android SDK - Including hidden APIs.\"",
-}
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index 857077d..79eface 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -436,6 +436,26 @@
     full_api_surface_stub: "android_module_lib_stubs_current_full.from-text",
 }
 
+// This module generates a stub jar that is a union of the test and module lib
+// non-updatable api contributions. Modules should not depend on the stub jar
+// generated from this module, as this module is strictly used for hiddenapi only.
+java_api_library {
+    name: "android-non-updatable.stubs.test_module_lib",
+    api_surface: "module_lib",
+    api_contributions: [
+        "api-stubs-docs-non-updatable.api.contribution",
+        "system-api-stubs-docs-non-updatable.api.contribution",
+        "test-api-stubs-docs-non-updatable.api.contribution",
+        "module-lib-api-stubs-docs-non-updatable.api.contribution",
+    ],
+    defaults: ["android-non-updatable_from_text_defaults"],
+    full_api_surface_stub: "android_test_module_lib_stubs_current.from-text",
+
+    // This module is only used for hiddenapi, and other modules should not
+    // depend on this module.
+    visibility: ["//visibility:private"],
+}
+
 java_defaults {
     name: "android_stubs_dists_default",
     dist: {
@@ -739,6 +759,30 @@
 }
 
 java_api_library {
+    name: "android_test_module_lib_stubs_current.from-text",
+    api_surface: "module-lib",
+    defaults: [
+        "android_stubs_current_contributions",
+        "android_system_stubs_current_contributions",
+        "android_test_stubs_current_contributions",
+        "android_module_lib_stubs_current_contributions",
+    ],
+    libs: [
+        "android_module_lib_stubs_current_full.from-text",
+        "stub-annotations",
+    ],
+    api_contributions: [
+        "test-api-stubs-docs-non-updatable.api.contribution",
+    ],
+
+    // This module is only used to build android-non-updatable.stubs.test_module_lib
+    // and other modules should not depend on this module.
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+java_api_library {
     name: "android_system_server_stubs_current.from-text",
     api_surface: "system-server",
     api_contributions: [
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 1812c2b..fd4e3df 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6634,12 +6634,6 @@
 android.security.attestationverification.AttestationVerificationManager
 android.security.keymaster.ExportResult$1
 android.security.keymaster.ExportResult
-android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub
-android.security.keymaster.IKeyAttestationApplicationIdProvider
-android.security.keymaster.KeyAttestationApplicationId$1
-android.security.keymaster.KeyAttestationApplicationId
-android.security.keymaster.KeyAttestationPackageInfo$1
-android.security.keymaster.KeyAttestationPackageInfo
 android.security.keymaster.KeyCharacteristics$1
 android.security.keymaster.KeyCharacteristics
 android.security.keymaster.KeymasterArgument$1
@@ -6664,7 +6658,13 @@
 android.security.keystore.BackendBusyException
 android.security.keystore.DelegatingX509Certificate
 android.security.keystore.DeviceIdAttestationException
+android.security.keystore.IKeyAttestationApplicationIdProvider$Stub
+android.security.keystore.IKeyAttestationApplicationIdProvider
+android.security.keystore.KeyAttestationApplicationId$Stub
+android.security.keystore.KeyAttestationApplicationId
 android.security.keystore.KeyAttestationException
+android.security.keystore.KeyAttestationPackageInfo$Stub
+android.security.keystore.KeyAttestationPackageInfo
 android.security.keystore.KeyExpiredException
 android.security.keystore.KeyGenParameterSpec$Builder
 android.security.keystore.KeyGenParameterSpec
@@ -6687,6 +6687,8 @@
 android.security.keystore.KeystoreResponse
 android.security.keystore.ParcelableKeyGenParameterSpec$1
 android.security.keystore.ParcelableKeyGenParameterSpec
+android.security.keystore.Signature$Stub
+android.security.keystore.Signature
 android.security.keystore.SecureKeyImportUnavailableException
 android.security.keystore.StrongBoxUnavailableException
 android.security.keystore.UserAuthArgs
diff --git a/core/api/current.txt b/core/api/current.txt
index 7ee12d1..e8988dc 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android {
 
   public final class Manifest {
@@ -29084,6 +29086,8 @@
     method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
     method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
     method public boolean isEnabled();
+    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled();
+    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
     method public boolean isSecureNfcEnabled();
     method public boolean isSecureNfcSupported();
     field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
@@ -32493,6 +32497,7 @@
     field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
     field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
     field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+    field @FlaggedApi("android.os.state_of_health_public") public static final int BATTERY_PROPERTY_STATE_OF_HEALTH = 10; // 0xa
     field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
     field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
     field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 7cfa1e3..01cf77a 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android {
 
   public static final class Manifest.permission {
diff --git a/core/api/module-lib-removed.txt b/core/api/module-lib-removed.txt
index d802177..14191eb 100644
--- a/core/api/module-lib-removed.txt
+++ b/core/api/module-lib-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 8b3696a..ede88a2 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.app {
 
   public class Notification implements android.os.Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 76f37b7..40eee4c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android {
 
   public static final class Manifest.permission {
@@ -10216,6 +10218,7 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
+    method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
     method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
@@ -10315,7 +10318,6 @@
     field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_CHARGING_POLICY = 9; // 0x9
     field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_FIRST_USAGE_DATE = 8; // 0x8
     field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_MANUFACTURING_DATE = 7; // 0x7
-    field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_STATE_OF_HEALTH = 10; // 0xa
     field public static final int CHARGING_POLICY_ADAPTIVE_AC = 3; // 0x3
     field public static final int CHARGING_POLICY_ADAPTIVE_AON = 2; // 0x2
     field public static final int CHARGING_POLICY_ADAPTIVE_LONGLIFE = 4; // 0x4
@@ -10383,8 +10385,8 @@
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportBleScanResults(@NonNull android.os.WorkSource, int);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportBleScanStarted(@NonNull android.os.WorkSource, boolean);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportBleScanStopped(@NonNull android.os.WorkSource, boolean);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void reportBluetoothOff(int, int, @NonNull String);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void reportBluetoothOn(int, int, @NonNull String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void reportBluetoothOff(int, int, @NonNull String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void reportBluetoothOn(int, int, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockAcquiredFromSource(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportMobileRadioPowerState(boolean, int);
diff --git a/core/api/system-removed.txt b/core/api/system-removed.txt
index 1c10356..4161330 100644
--- a/core/api/system-removed.txt
+++ b/core/api/system-removed.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.app {
 
   public class AppOpsManager {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 70377ab..8d0e396 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android {
 
   public static final class Manifest.permission {
diff --git a/core/api/test-removed.txt b/core/api/test-removed.txt
index d802177..14191eb 100644
--- a/core/api/test-removed.txt
+++ b/core/api/test-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 5091b52..70864d5 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -23,11 +23,6 @@
     visibility: ["//frameworks/base"],
 }
 
-filegroup {
-    name: "IKeyAttestationApplicationIdProvider.aidl",
-    srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"],
-}
-
 aidl_library {
     name: "IDropBoxManagerService_aidl",
     srcs: [
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 7ed3a1d..6a51171 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -60,6 +60,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockPatternView;
 import com.android.internal.widget.LockscreenCredential;
+import com.android.internal.widget.PasswordValidationError;
 import com.android.internal.widget.VerifyCredentialResponse;
 
 import java.nio.charset.Charset;
@@ -916,17 +917,14 @@
         if (!checkInitialLockMethodUsage()) {
             return false;
         }
+        Objects.requireNonNull(password, "Password cannot be null.");
         complexity = PasswordMetrics.sanitizeComplexityLevel(complexity);
-        // TODO: b/131755827 add devicePolicyManager support for Auto
-        DevicePolicyManager devicePolicyManager =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         PasswordMetrics adminMetrics =
-                devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId());
-        // Check if the password fits the mold of a pin or pattern.
-        boolean isPinOrPattern = lockType != PASSWORD;
-
-        return PasswordMetrics.validatePassword(
-                adminMetrics, complexity, isPinOrPattern, password).size() == 0;
+                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
+        try (LockscreenCredential credential = createLockscreenCredential(lockType, password)) {
+            return PasswordMetrics.validateCredential(adminMetrics, complexity,
+                    credential).size() == 0;
+        }
     }
 
     /**
@@ -945,11 +943,8 @@
             return -1;
         }
         complexity = PasswordMetrics.sanitizeComplexityLevel(complexity);
-        // TODO: b/131755827 add devicePolicyManager support for Auto
-        DevicePolicyManager devicePolicyManager =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
         PasswordMetrics adminMetrics =
-                devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId());
+                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
         PasswordMetrics minMetrics =
                 PasswordMetrics.applyComplexity(adminMetrics, isPin, complexity);
         return minMetrics.length;
@@ -1171,6 +1166,14 @@
                 currentLockType, currentPassword);
         LockscreenCredential newCredential = createLockscreenCredential(
                 newLockType, newPassword);
+        PasswordMetrics adminMetrics =
+                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
+        List<PasswordValidationError> errors = PasswordMetrics.validateCredential(adminMetrics,
+                DevicePolicyManager.PASSWORD_COMPLEXITY_NONE, newCredential);
+        if (!errors.isEmpty()) {
+            Log.e(TAG, "New credential is not valid: " + errors.get(0));
+            return false;
+        }
         return mLockPatternUtils.setLockCredential(newCredential, currentCredential, userId);
     }
 
diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java
index ab48791..dd31175 100644
--- a/core/java/android/app/admin/PasswordMetrics.java
+++ b/core/java/android/app/admin/PasswordMetrics.java
@@ -30,6 +30,7 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
 import static com.android.internal.widget.LockPatternUtils.MIN_LOCK_PASSWORD_SIZE;
+import static com.android.internal.widget.LockPatternUtils.MIN_LOCK_PATTERN_SIZE;
 import static com.android.internal.widget.PasswordValidationError.CONTAINS_INVALID_CHARACTERS;
 import static com.android.internal.widget.PasswordValidationError.CONTAINS_SEQUENCE;
 import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_DIGITS;
@@ -134,17 +135,6 @@
         }
     }
 
-    private static boolean hasInvalidCharacters(byte[] password) {
-        // Allow non-control Latin-1 characters only.
-        for (byte b : password) {
-            char c = (char) b;
-            if (c < 32 || c > 127) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     @Override
     public int describeContents() {
         return 0;
@@ -189,19 +179,15 @@
     };
 
     /**
-     * Returns the {@code PasswordMetrics} for a given credential.
-     *
-     * If the credential is a pin or a password, equivalent to
-     * {@link #computeForPasswordOrPin(byte[], boolean)}. {@code credential} cannot be null
-     * when {@code type} is
-     * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}.
+     * Returns the {@code PasswordMetrics} for the given credential.
      */
     public static PasswordMetrics computeForCredential(LockscreenCredential credential) {
         if (credential.isPassword() || credential.isPin()) {
-            return PasswordMetrics.computeForPasswordOrPin(credential.getCredential(),
-                    credential.isPin());
+            return computeForPasswordOrPin(credential.getCredential(), credential.isPin());
         } else if (credential.isPattern())  {
-            return new PasswordMetrics(CREDENTIAL_TYPE_PATTERN);
+            PasswordMetrics metrics = new PasswordMetrics(CREDENTIAL_TYPE_PATTERN);
+            metrics.length = credential.size();
+            return metrics;
         } else if (credential.isNone()) {
             return new PasswordMetrics(CREDENTIAL_TYPE_NONE);
         } else {
@@ -210,10 +196,10 @@
     }
 
     /**
-     * Returns the {@code PasswordMetrics} for a given password or pin
+     * Returns the {@code PasswordMetrics} for the given password or pin.
      */
-    public static PasswordMetrics computeForPasswordOrPin(byte[] password, boolean isPin) {
-        // Analyse the characters used
+    private static PasswordMetrics computeForPasswordOrPin(byte[] credential, boolean isPin) {
+        // Analyze the characters used.
         int letters = 0;
         int upperCase = 0;
         int lowerCase = 0;
@@ -221,8 +207,8 @@
         int symbols = 0;
         int nonLetter = 0;
         int nonNumeric = 0;
-        final int length = password.length;
-        for (byte b : password) {
+        final int length = credential.length;
+        for (byte b : credential) {
             switch (categoryChar((char) b)) {
                 case CHAR_LOWER_CASE:
                     letters++;
@@ -247,7 +233,7 @@
         }
 
         final int credType = isPin ? CREDENTIAL_TYPE_PIN : CREDENTIAL_TYPE_PASSWORD;
-        final int seqLength = maxLengthSequence(password);
+        final int seqLength = maxLengthSequence(credential);
         return new PasswordMetrics(credType, length, letters, upperCase, lowerCase,
                 numeric, symbols, nonLetter, nonNumeric, seqLength);
     }
@@ -513,26 +499,24 @@
     }
 
     /**
-     * Validates password against minimum metrics and complexity.
+     * Validates a proposed lockscreen credential against minimum metrics and complexity.
      *
-     * @param adminMetrics - minimum metrics to satisfy admin requirements.
-     * @param minComplexity - minimum complexity imposed by the requester.
-     * @param isPin - whether it is PIN that should be only digits
-     * @param password - password to validate.
-     * @return a list of password validation errors. An empty list means the password is OK.
+     * @param adminMetrics minimum metrics to satisfy admin requirements
+     * @param minComplexity minimum complexity imposed by the requester
+     * @param credential the proposed lockscreen credential
+     *
+     * @return a list of validation errors. An empty list means the credential is OK.
      *
      * TODO: move to PasswordPolicy
      */
-    public static List<PasswordValidationError> validatePassword(
-            PasswordMetrics adminMetrics, int minComplexity, boolean isPin, byte[] password) {
-
-        if (hasInvalidCharacters(password)) {
+    public static List<PasswordValidationError> validateCredential(
+            PasswordMetrics adminMetrics, int minComplexity, LockscreenCredential credential) {
+        if (credential.hasInvalidChars()) {
             return Collections.singletonList(
                     new PasswordValidationError(CONTAINS_INVALID_CHARACTERS, 0));
         }
-
-        final PasswordMetrics enteredMetrics = computeForPasswordOrPin(password, isPin);
-        return validatePasswordMetrics(adminMetrics, minComplexity, enteredMetrics);
+        PasswordMetrics actualMetrics = computeForCredential(credential);
+        return validatePasswordMetrics(adminMetrics, minComplexity, actualMetrics);
     }
 
     /**
@@ -555,9 +539,18 @@
                 || !bucket.allowsCredType(actualMetrics.credType)) {
             return Collections.singletonList(new PasswordValidationError(WEAK_CREDENTIAL_TYPE, 0));
         }
-        if (actualMetrics.credType != CREDENTIAL_TYPE_PASSWORD
-                && actualMetrics.credType != CREDENTIAL_TYPE_PIN) {
-            return Collections.emptyList(); // Nothing to check for pattern or none.
+        if (actualMetrics.credType == CREDENTIAL_TYPE_PATTERN) {
+            // For pattern, only need to check the length against the hardcoded minimum.  If the
+            // pattern length is unavailable (e.g., PasswordMetrics that was stored on-disk before
+            // the pattern length started being included in it), assume it is okay.
+            if (actualMetrics.length != 0 && actualMetrics.length < MIN_LOCK_PATTERN_SIZE) {
+                return Collections.singletonList(new PasswordValidationError(TOO_SHORT,
+                            MIN_LOCK_PATTERN_SIZE));
+            }
+            return Collections.emptyList();
+        }
+        if (actualMetrics.credType == CREDENTIAL_TYPE_NONE) {
+            return Collections.emptyList(); // Nothing to check for none.
         }
 
         if (actualMetrics.credType == CREDENTIAL_TYPE_PIN && actualMetrics.nonNumeric > 0) {
diff --git a/core/java/android/companion/virtualnative/OWNERS b/core/java/android/companion/virtualnative/OWNERS
new file mode 100644
index 0000000..2968104
--- /dev/null
+++ b/core/java/android/companion/virtualnative/OWNERS
@@ -0,0 +1 @@
+include /services/companion/java/com/android/server/companion/virtual/OWNERS
diff --git a/core/java/android/content/pm/Signature.aidl b/core/java/android/content/pm/Signature.aidl
deleted file mode 100644
index 36c127a..0000000
--- a/core/java/android/content/pm/Signature.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT 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.content.pm;
-
-/* For the key attestation application id provider service we needed a native implementation
- * of the Signature parcelable because the service is used by the native keystore.
- * The native implementation is now located at
- * system/security/keystore/Signature.cpp
- * and
- * system/security/keystore/include/keystore/Signature.h.
- * and can be used by linking against libkeystore_binder.
- *
- * This is not the best arrangement. If you, dear reader, happen to implement native implementations
- * for the package manager's parcelables, consider moving Signature.cpp/.h to your library and
- * adjust keystore's dependencies accordingly. Thank you.
- */
-parcelable Signature cpp_header "keystore/Signature.h";
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 151f819..6ac1efb 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -114,8 +114,8 @@
     }
 
     /**
-     * Get {@link PresentationSession} object.
-     * @return {@link PresentationSession} object or null if this doesn't contain one.
+     * Get {@link KeyAgreement} object.
+     * @return {@link KeyAgreement} object or null if this doesn't contain one.
      */
     @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
     public KeyAgreement getKeyAgreement() {
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index a6d8caf..0c95c2e 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -79,4 +79,9 @@
     Map getTagIntentAppPreferenceForUser(int userId);
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
     int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
+
+    boolean isReaderOptionEnabled();
+    boolean isReaderOptionSupported();
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+    boolean enableReaderOption(boolean enable);
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 1307dfc..4658630 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -17,6 +17,7 @@
 package android.nfc;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1826,6 +1827,97 @@
     }
 
     /**
+     * Sets NFC Reader option feature.
+     * <p>This API is for the Settings application.
+     * @return True if successful
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean enableReaderOption(boolean enable) {
+        if (!sHasNfcFeature) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return sService.enableReaderOption(enable);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return false;
+            }
+            try {
+                return sService.enableReaderOption(enable);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Checks if the device supports NFC Reader option functionality.
+     *
+     * @return True if device supports NFC Reader option, false otherwise
+     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
+    public boolean isReaderOptionSupported() {
+        if (!sHasNfcFeature) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return sService.isReaderOptionSupported();
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return false;
+            }
+            try {
+                return sService.isReaderOptionSupported();
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Checks NFC Reader option feature is enabled.
+     *
+     * @return True if NFC Reader option  is enabled, false otherwise
+     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
+     * @throws UnsupportedOperationException if device doesn't support
+     *         NFC Reader option functionality. {@link #isReaderOptionSupported}
+     */
+    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
+    public boolean isReaderOptionEnabled() {
+        if (!sHasNfcFeature) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return sService.isReaderOptionEnabled();
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return false;
+            }
+            try {
+                return sService.isReaderOptionEnabled();
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return false;
+        }
+    }
+
+    /**
      * Enable NDEF Push feature.
      * <p>This API is for the Settings application.
      * @hide
diff --git a/core/java/android/nfc/flags.aconfig b/core/java/android/nfc/flags.aconfig
index e3faf39..55b0b42 100644
--- a/core/java/android/nfc/flags.aconfig
+++ b/core/java/android/nfc/flags.aconfig
@@ -6,3 +6,10 @@
     description: "Flag for NFC mainline changes"
     bug: "292140387"
 }
+
+flag {
+    name: "enable_nfc_reader_option"
+    namespace: "nfc"
+    description: "Flag for NFC reader option API changes"
+    bug: "291187960"
+}
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 092923e..6a4ec9b 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -16,7 +16,10 @@
 
 package android.os;
 
+import static android.os.Flags.FLAG_STATE_OF_HEALTH_PUBLIC;
+
 import android.Manifest.permission;
+import android.annotation.FlaggedApi;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
@@ -354,17 +357,11 @@
     public static final int BATTERY_PROPERTY_CHARGING_POLICY = 9;
 
     /**
-     *
-     * Percentage representing the measured battery state of health (remaining
-     * estimated full charge capacity relative to the rated capacity in %).
-     *
-     * <p class="note">
-     * The sender must hold the {@link android.Manifest.permission#BATTERY_STATS} permission.
-     *
-     * @hide
+     * Percentage representing the measured battery state of health.
+     * This is the remaining estimated full charge capacity relative
+     * to the rated capacity in %.
      */
-    @RequiresPermission(permission.BATTERY_STATS)
-    @SystemApi
+    @FlaggedApi(FLAG_STATE_OF_HEALTH_PUBLIC)
     public static final int BATTERY_PROPERTY_STATE_OF_HEALTH = 10;
 
     private final Context mContext;
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index 955fad3..3abe9a0 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -520,8 +520,9 @@
      * @param uid calling package uid
      * @param reason why Bluetooth has been turned on
      * @param packageName package responsible for this change
-     * @Deprecated Bluetooth self report its state and no longer call this
+     * @deprecated Bluetooth self report its state and no longer call this
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
     public void reportBluetoothOn(int uid, int reason, @NonNull String packageName) {
     }
@@ -532,8 +533,9 @@
      * @param uid calling package uid
      * @param reason why Bluetooth has been turned on
      * @param packageName package responsible for this change
-     * @Deprecated Bluetooth self report its state and no longer call this
+     * @deprecated Bluetooth self report its state and no longer call this
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
     public void reportBluetoothOff(int uid, int reason, @NonNull String packageName) {
     }
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 851aa6d..77229c4 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,6 +1,13 @@
 package: "android.os"
 
 flag {
+    name: "state_of_health_public"
+    namespace: "system_sw_battery"
+    description: "Feature flag for making state_of_health a public api."
+    bug: "288842045"
+}
+
+flag {
     name: "disallow_cellular_null_ciphers_restriction"
     namespace: "cellular_security"
     description: "Guards a new UserManager user restriction that admins can use to require cellular encryption on their managed devices."
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index baeb1aa..9cdb9ce 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10442,20 +10442,6 @@
                 "assist_long_press_home_enabled";
 
         /**
-         * Control whether Trust Agents are in active unlock or extend unlock mode.
-         * @hide
-         */
-        @Readable
-        public static final String TRUST_AGENTS_EXTEND_UNLOCK = "trust_agents_extend_unlock";
-
-        /**
-         * Control whether the screen locks when trust is lost.
-         * @hide
-         */
-        @Readable
-        public static final String LOCK_SCREEN_WHEN_TRUST_LOST = "lock_screen_when_trust_lost";
-
-        /**
          * Control whether Night display is currently activated.
          * @hide
          */
diff --git a/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl b/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl
deleted file mode 100644
index dbffd5f..0000000
--- a/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keymaster;
-
-import android.security.keymaster.KeyAttestationApplicationId;
-import android.security.keymaster.KeyAttestationPackageInfo;
-import android.content.pm.Signature;
-
-/**
- * This must be kept manually in sync with system/security/keystore until AIDL
- * can generate both Java and C++ bindings.
- *
- * @hide
- */
-interface IKeyAttestationApplicationIdProvider {
-    /* keep in sync with /system/security/keystore/keystore_attestation_id.cpp */
-    KeyAttestationApplicationId getKeyAttestationApplicationId(int uid);
-}
diff --git a/core/java/android/security/keymaster/KeyAttestationApplicationId.aidl b/core/java/android/security/keymaster/KeyAttestationApplicationId.aidl
deleted file mode 100644
index 9f6ff58..0000000
--- a/core/java/android/security/keymaster/KeyAttestationApplicationId.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keymaster;
-
-/* The cpp_header is relative to system/security/keystore/include
- * Link against libkeystore_binder to make use of the native implementation of this Parcelable.
- */
-parcelable KeyAttestationApplicationId cpp_header "keystore/KeyAttestationApplicationId.h";
diff --git a/core/java/android/security/keymaster/KeyAttestationApplicationId.java b/core/java/android/security/keymaster/KeyAttestationApplicationId.java
deleted file mode 100644
index 670f30e1b..0000000
--- a/core/java/android/security/keymaster/KeyAttestationApplicationId.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keymaster;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * @hide
- * The information aggregated by this class is used by keystore to identify a caller of the
- * keystore API toward a remote party. It aggregates multiple PackageInfos because keystore
- * can only determine a caller by uid granularity, and a uid can be shared by multiple packages.
- * The remote party must decide if it trusts all of the packages enough to consider the
- * confidentiality of the key material in question intact.
- */
-public class KeyAttestationApplicationId implements Parcelable {
-    private final KeyAttestationPackageInfo[] mAttestationPackageInfos;
-
-    /**
-     * @param mAttestationPackageInfos
-     */
-    public KeyAttestationApplicationId(KeyAttestationPackageInfo[] mAttestationPackageInfos) {
-        super();
-        this.mAttestationPackageInfos = mAttestationPackageInfos;
-    }
-
-    /**
-     * @return the mAttestationPackageInfos
-     */
-    public KeyAttestationPackageInfo[] getAttestationPackageInfos() {
-        return mAttestationPackageInfos;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeTypedArray(mAttestationPackageInfos, flags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<KeyAttestationApplicationId> CREATOR
-            = new Parcelable.Creator<KeyAttestationApplicationId>() {
-        @Override
-        public KeyAttestationApplicationId createFromParcel(Parcel source) {
-            return new KeyAttestationApplicationId(source);
-        }
-
-        @Override
-        public KeyAttestationApplicationId[] newArray(int size) {
-            return new KeyAttestationApplicationId[size];
-        }
-    };
-
-    KeyAttestationApplicationId(Parcel source) {
-        mAttestationPackageInfos = source.createTypedArray(KeyAttestationPackageInfo.CREATOR);
-    }
-}
diff --git a/core/java/android/security/keymaster/KeyAttestationPackageInfo.aidl b/core/java/android/security/keymaster/KeyAttestationPackageInfo.aidl
deleted file mode 100644
index f8b843b..0000000
--- a/core/java/android/security/keymaster/KeyAttestationPackageInfo.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keymaster;
-
-/* The cpp_header is relative to system/security/keystore/include
- * Link against libkeystore_binder to make use of the native implementation of this Parcelable.
- */
-parcelable KeyAttestationPackageInfo cpp_header "keystore/KeyAttestationPackageInfo.h";
diff --git a/core/java/android/security/keymaster/KeyAttestationPackageInfo.java b/core/java/android/security/keymaster/KeyAttestationPackageInfo.java
deleted file mode 100644
index c0b8d8d..0000000
--- a/core/java/android/security/keymaster/KeyAttestationPackageInfo.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keymaster;
-
-import android.content.pm.Signature;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * @hide
- * This class constitutes and excerpt from the PackageManager's PackageInfo for the purpose of
- * key attestation. It is part of the KeyAttestationApplicationId, which is used by
- * keystore to identify the caller of the keystore API towards a remote party.
- */
-public class KeyAttestationPackageInfo implements Parcelable {
-    private final String mPackageName;
-    private final long mPackageVersionCode;
-    private final Signature[] mPackageSignatures;
-
-    /**
-     * @param mPackageName
-     * @param mPackageVersionCode
-     * @param mPackageSignatures
-     */
-    public KeyAttestationPackageInfo(
-            String mPackageName, long mPackageVersionCode, Signature[] mPackageSignatures) {
-        super();
-        this.mPackageName = mPackageName;
-        this.mPackageVersionCode = mPackageVersionCode;
-        this.mPackageSignatures = mPackageSignatures;
-    }
-    /**
-     * @return the mPackageName
-     */
-    public String getPackageName() {
-        return mPackageName;
-    }
-    /**
-     * @return the mPackageVersionCode
-     */
-    public long getPackageVersionCode() {
-        return mPackageVersionCode;
-    }
-    /**
-     * @return the mPackageSignatures
-     */
-    public Signature[] getPackageSignatures() {
-        return mPackageSignatures;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mPackageName);
-        dest.writeLong(mPackageVersionCode);
-        dest.writeTypedArray(mPackageSignatures, flags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<KeyAttestationPackageInfo> CREATOR
-            = new Parcelable.Creator<KeyAttestationPackageInfo>() {
-        @Override
-        public KeyAttestationPackageInfo createFromParcel(Parcel source) {
-            return new KeyAttestationPackageInfo(source);
-        }
-
-        @Override
-        public KeyAttestationPackageInfo[] newArray(int size) {
-            return new KeyAttestationPackageInfo[size];
-        }
-    };
-
-    private KeyAttestationPackageInfo(Parcel source) {
-        mPackageName = source.readString();
-        mPackageVersionCode = source.readLong();
-        mPackageSignatures = source.createTypedArray(Signature.CREATOR);
-    }
-}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0d0bfe3..d702963 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2536,7 +2536,7 @@
         final int childrenCount = mChildrenCount;
         if (childrenCount != 0) {
             final float x = event.getXDispatchLocation(0);
-            final float y = event.getXDispatchLocation(0);
+            final float y = event.getYDispatchLocation(0);
 
             final ArrayList<View> preorderedList = buildOrderedChildList();
             final boolean customOrder = preorderedList == null
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 490ec35..a1f8de4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -96,7 +96,7 @@
     public static final int MIN_LOCK_PATTERN_SIZE = 4;
 
     /**
-     * The minimum size of a valid password.
+     * The minimum size of a valid password or PIN.
      */
     public static final int MIN_LOCK_PASSWORD_SIZE = 4;
 
@@ -171,7 +171,6 @@
      */
     public static final int USER_FRP = UserHandle.USER_NULL + 1;
 
-    public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
     public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
     @Deprecated
     public final static String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
@@ -597,16 +596,6 @@
     }
 
     /**
-     * Return true if the user has ever chosen a pattern.  This is true even if the pattern is
-     * currently cleared.
-     *
-     * @return True if the user has ever chosen a pattern.
-     */
-    public boolean isPatternEverChosen(int userId) {
-        return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, userId);
-    }
-
-    /**
      * Returns the length of the PIN set by a particular user.
      * @param userId user id of the user whose pin length we have to return
      * @return
@@ -639,13 +628,6 @@
             return false;
         }
     }
-    /**
-     * Records that the user has chosen a pattern at some time, even if the pattern is
-     * currently cleared.
-     */
-    public void reportPatternWasChosen(int userId) {
-        setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);
-    }
 
     /**
      * Used by device policy manager to validate the current password
@@ -771,7 +753,6 @@
      * and return false if the given credential is wrong.
      * @throws RuntimeException if password change encountered an unrecoverable error.
      * @throws UnsupportedOperationException secure lockscreen is not supported on this device.
-     * @throws IllegalArgumentException if new credential is too short.
      */
     public boolean setLockCredential(@NonNull LockscreenCredential newCredential,
             @NonNull LockscreenCredential savedCredential, int userHandle) {
@@ -779,7 +760,6 @@
             throw new UnsupportedOperationException(
                     "This operation requires the lock screen feature.");
         }
-        newCredential.checkLength();
 
         try {
             if (!getLockSettings().setLockCredential(newCredential, savedCredential, userHandle)) {
@@ -1543,7 +1523,6 @@
             throw new UnsupportedOperationException(
                     "This operation requires the lock screen feature.");
         }
-        credential.checkLength();
         LockSettingsInternal localService = getLockSettingsInternal();
 
         return localService.setLockCredentialWithToken(credential, tokenHandle, token, userHandle);
diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 03e7fd1..c88763c 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -60,10 +60,24 @@
 public class LockscreenCredential implements Parcelable, AutoCloseable {
 
     private final int mType;
-    // Stores raw credential bytes, or null if credential has been zeroized. An empty password
+    // Stores raw credential bytes, or null if credential has been zeroized. A none credential
     // is represented as a byte array of length 0.
     private byte[] mCredential;
 
+    // This indicates that the credential used characters outside ASCII 32–127.
+    //
+    // Such credentials were never intended to be allowed.  However, Android 10–14 had a bug where
+    // conversion from the chars the user entered to the credential bytes used a simple truncation.
+    // Thus, any 'char' whose remainder mod 256 was in the range 32–127 was accepted and was
+    // equivalent to some ASCII character.  For example, ™, which is U+2122, was truncated to ASCII
+    // 0x22 which is the double-quote character ".
+    //
+    // We have to continue to allow a LockscreenCredential to be constructed with this bug, so that
+    // existing devices can be unlocked if their password used this bug.  However, we prevent new
+    // passwords that use this bug from being set.  The boolean below keeps track of the information
+    // needed to do that check, since the conversion to mCredential may have been lossy.
+    private final boolean mHasInvalidChars;
+
     /**
      * Private constructor, use static builder methods instead.
      *
@@ -71,7 +85,7 @@
      * LockscreenCredential will only store the reference internally without copying. This is to
      * minimize the number of extra copies introduced.
      */
-    private LockscreenCredential(int type, byte[] credential) {
+    private LockscreenCredential(int type, byte[] credential, boolean hasInvalidChars) {
         Objects.requireNonNull(credential);
         if (type == CREDENTIAL_TYPE_NONE) {
             Preconditions.checkArgument(credential.length == 0);
@@ -80,17 +94,28 @@
             Preconditions.checkArgument(type == CREDENTIAL_TYPE_PIN
                     || type == CREDENTIAL_TYPE_PASSWORD
                     || type == CREDENTIAL_TYPE_PATTERN);
-            Preconditions.checkArgument(credential.length > 0);
+            // Do not validate credential.length yet.  All non-none credentials have a minimum
+            // length requirement; however, one of the uses of LockscreenCredential is to represent
+            // a proposed credential that might be too short.  For example, a LockscreenCredential
+            // with type CREDENTIAL_TYPE_PIN and length 0 represents an attempt to set an empty PIN.
+            // This differs from an actual attempt to set a none credential.  We have to allow the
+            // LockscreenCredential object to be constructed so that the validation logic can run,
+            // even though the validation logic will ultimately reject the credential as too short.
         }
         mType = type;
         mCredential = credential;
+        mHasInvalidChars = hasInvalidChars;
+    }
+
+    private LockscreenCredential(int type, CharSequence credential) {
+        this(type, charsToBytesTruncating(credential), hasInvalidChars(credential));
     }
 
     /**
-     * Creates a LockscreenCredential object representing empty password.
+     * Creates a LockscreenCredential object representing a none credential.
      */
     public static LockscreenCredential createNone() {
-        return new LockscreenCredential(CREDENTIAL_TYPE_NONE, new byte[0]);
+        return new LockscreenCredential(CREDENTIAL_TYPE_NONE, new byte[0], false);
     }
 
     /**
@@ -98,15 +123,14 @@
      */
     public static LockscreenCredential createPattern(@NonNull List<LockPatternView.Cell> pattern) {
         return new LockscreenCredential(CREDENTIAL_TYPE_PATTERN,
-                LockPatternUtils.patternToByteArray(pattern));
+                LockPatternUtils.patternToByteArray(pattern), /* hasInvalidChars= */ false);
     }
 
     /**
      * Creates a LockscreenCredential object representing the given alphabetic password.
      */
     public static LockscreenCredential createPassword(@NonNull CharSequence password) {
-        return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD,
-                charSequenceToByteArray(password));
+        return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD, password);
     }
 
     /**
@@ -117,20 +141,19 @@
      */
     public static LockscreenCredential createManagedPassword(@NonNull byte[] password) {
         return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD,
-                Arrays.copyOf(password, password.length));
+                Arrays.copyOf(password, password.length), /* hasInvalidChars= */ false);
     }
 
     /**
      * Creates a LockscreenCredential object representing the given numeric PIN.
      */
     public static LockscreenCredential createPin(@NonNull CharSequence pin) {
-        return new LockscreenCredential(CREDENTIAL_TYPE_PIN,
-                charSequenceToByteArray(pin));
+        return new LockscreenCredential(CREDENTIAL_TYPE_PIN, pin);
     }
 
     /**
      * Creates a LockscreenCredential object representing the given alphabetic password.
-     * If the supplied password is empty, create an empty credential object.
+     * If the supplied password is empty, create a none credential object.
      */
     public static LockscreenCredential createPasswordOrNone(@Nullable CharSequence password) {
         if (TextUtils.isEmpty(password)) {
@@ -142,7 +165,7 @@
 
     /**
      * Creates a LockscreenCredential object representing the given numeric PIN.
-     * If the supplied password is empty, create an empty credential object.
+     * If the supplied password is empty, create a none credential object.
      */
     public static LockscreenCredential createPinOrNone(@Nullable CharSequence pin) {
         if (TextUtils.isEmpty(pin)) {
@@ -175,7 +198,7 @@
         return mCredential;
     }
 
-    /** Returns whether this is an empty credential */
+    /** Returns whether this is a none credential */
     public boolean isNone() {
         ensureNotZeroized();
         return mType == CREDENTIAL_TYPE_NONE;
@@ -205,10 +228,17 @@
         return mCredential.length;
     }
 
+    /** Returns true if this credential was constructed with any chars outside the allowed range */
+    public boolean hasInvalidChars() {
+        ensureNotZeroized();
+        return mHasInvalidChars;
+    }
+
     /** Create a copy of the credential */
     public LockscreenCredential duplicate() {
         return new LockscreenCredential(mType,
-                mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null);
+                mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null,
+                mHasInvalidChars);
     }
 
     /**
@@ -222,27 +252,37 @@
     }
 
     /**
-     * Check if the credential meets minimal length requirement.
+     * Checks whether the credential meets basic requirements for setting it as a new credential.
      *
-     * @throws IllegalArgumentException if the credential is too short.
+     * This is redundant if {@link android.app.admin.PasswordMetrics#validateCredential()}, which
+     * does more comprehensive checks, is correctly called first (which it should be).
+     *
+     * @throws IllegalArgumentException if the credential contains invalid characters or is too
+     * short
      */
-    public void checkLength() {
-        if (isNone()) {
-            return;
+    public void validateBasicRequirements() {
+        if (mHasInvalidChars) {
+            throw new IllegalArgumentException("credential contains invalid characters");
         }
-        if (isPattern()) {
-            if (size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
-                throw new IllegalArgumentException("pattern must not be null and at least "
-                        + LockPatternUtils.MIN_LOCK_PATTERN_SIZE + " dots long.");
-            }
-            return;
-        }
-        if (isPassword() || isPin()) {
-            if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
-                throw new IllegalArgumentException("password must not be null and at least "
-                        + "of length " + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE);
-            }
-            return;
+        switch (getType()) {
+            case CREDENTIAL_TYPE_PATTERN:
+                if (size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
+                    throw new IllegalArgumentException("pattern must be at least "
+                            + LockPatternUtils.MIN_LOCK_PATTERN_SIZE + " dots long.");
+                }
+                break;
+            case CREDENTIAL_TYPE_PIN:
+                if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
+                    throw new IllegalArgumentException("PIN must be at least "
+                            + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE + " digits long.");
+                }
+                break;
+            case CREDENTIAL_TYPE_PASSWORD:
+                if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
+                    throw new IllegalArgumentException("password must be at least "
+                            + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE + " characters long.");
+                }
+                break;
         }
     }
 
@@ -317,6 +357,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mType);
         dest.writeByteArray(mCredential);
+        dest.writeBoolean(mHasInvalidChars);
     }
 
     public static final Parcelable.Creator<LockscreenCredential> CREATOR =
@@ -324,7 +365,8 @@
 
         @Override
         public LockscreenCredential createFromParcel(Parcel source) {
-            return new LockscreenCredential(source.readInt(), source.createByteArray());
+            return new LockscreenCredential(source.readInt(), source.createByteArray(),
+                    source.readBoolean());
         }
 
         @Override
@@ -346,7 +388,7 @@
     @Override
     public int hashCode() {
         // Effective Java — Always override hashCode when you override equals
-        return Objects.hash(mType, Arrays.hashCode(mCredential));
+        return Objects.hash(mType, Arrays.hashCode(mCredential), mHasInvalidChars);
     }
 
     @Override
@@ -354,20 +396,45 @@
         if (o == this) return true;
         if (!(o instanceof LockscreenCredential)) return false;
         final LockscreenCredential other = (LockscreenCredential) o;
-        return mType == other.mType && Arrays.equals(mCredential, other.mCredential);
+        return mType == other.mType && Arrays.equals(mCredential, other.mCredential)
+            && mHasInvalidChars == other.mHasInvalidChars;
+    }
+
+    private static boolean hasInvalidChars(CharSequence chars) {
+        //
+        // Consider the password to have invalid characters if it contains any non-ASCII characters
+        // or control characters.  There are multiple reasons for this restriction:
+        //
+        // - Non-ASCII characters might only be possible to enter on a third-party keyboard app
+        //   (IME) that is available when setting the password but not when verifying it after a
+        //   reboot.  This can happen if the keyboard is not direct boot aware or gets uninstalled.
+        //
+        // - Unicode strings that look identical to the user can map to different byte[].  Yet, only
+        //   one byte[] can be accepted.  Unicode normalization can solve this problem to some
+        //   extent, but still many Unicode characters look similar and could cause confusion.
+        //
+        // - For backwards compatibility reasons, the upper 8 bits of the 16-bit 'chars' are
+        //   discarded by charsToBytesTruncating().  Thus, as-is passwords with characters above
+        //   U+00FF (255) are not as secure as they should be.  IMPORTANT: Do not change the below
+        //   code to allow characters above U+00FF (255) without fixing this issue!
+        //
+        for (int i = 0; i < chars.length(); i++) {
+            char c = chars.charAt(i);
+            if (c < 32 || c > 127) {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
-     * Converts a CharSequence to a byte array without requiring a toString(), which creates an
-     * additional copy.
+     * Converts a CharSequence to a byte array, intentionally truncating chars greater than 255 for
+     * backwards compatibility reasons.  See {@link #mHasInvalidChars}.
      *
      * @param chars The CharSequence to convert
      * @return A byte array representing the input
      */
-    private static byte[] charSequenceToByteArray(CharSequence chars) {
-        if (chars == null) {
-            return new byte[0];
-        }
+    private static byte[] charsToBytesTruncating(CharSequence chars) {
         byte[] bytes = new byte[chars.length()];
         for (int i = 0; i < chars.length(); i++) {
             bytes[i] = (byte) chars.charAt(i);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 55382cc..bfd80a9e 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -157,12 +157,8 @@
 // ****************************************************************************
 // ****************************************************************************
 
-static constexpr int32_t PROXY_WARN_INTERVAL = 5000;
 static constexpr uint32_t GC_INTERVAL = 1000;
 
-static std::atomic<uint32_t> gNumProxies(0);
-static std::atomic<uint32_t> gProxiesWarned(0);
-
 // Number of GlobalRefs held by JavaBBinders.
 static std::atomic<uint32_t> gNumLocalRefsCreated(0);
 static std::atomic<uint32_t> gNumLocalRefsDeleted(0);
@@ -842,19 +838,7 @@
         return NULL;
     }
     BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
-    if (actualNativeData == nativeData) {
-        // Created a new Proxy
-        uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
-        uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
-        if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
-            // Multiple threads can get here, make sure only one of them gets to
-            // update the warn counter.
-            if (gProxiesWarned.compare_exchange_strong(numLastWarned,
-                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
-                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
-            }
-        }
-    } else {
+    if (actualNativeData != nativeData) {
         delete nativeData;
     }
 
@@ -1209,7 +1193,7 @@
 
 jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz)
 {
-    return gNumProxies.load();
+    return BpBinder::getBinderProxyCount();
 }
 
 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz)
@@ -1494,7 +1478,6 @@
             nativeData->mObject.get(), nativeData->mOrgue.get());
     delete nativeData;
     IPCThreadState::self()->flushCommands();
-    --gNumProxies;
 }
 
 JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 58f97b0..93048ea 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1022,7 +1022,7 @@
          requires swapping ROTATION_90 and ROTATION_270.
          TODO(b/265991392): This should eventually be configured and parsed in
           display_settings.xml -->
-    <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">true</bool>
+    <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">false</bool>
 
     <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. -->
     <integer-array name="config_availableColorModes">
diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp
index 436f058..136bd79 100644
--- a/core/tests/BroadcastRadioTests/Android.bp
+++ b/core/tests/BroadcastRadioTests/Android.bp
@@ -38,7 +38,7 @@
     static_libs: [
         "services.core",
         "androidx.test.rules",
-        "truth-prebuilt",
+        "truth",
         "testng",
         "mockito-target-extended",
     ],
diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp
index 8c5d6d5..0e3bc65 100644
--- a/core/tests/GameManagerTests/Android.bp
+++ b/core/tests/GameManagerTests/Android.bp
@@ -30,7 +30,7 @@
         "frameworks-base-testutils",
         "junit",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: ["android.test.runner"],
     platform_apis: true,
diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp
index 6f2366e..b631df1 100644
--- a/core/tests/PackageInstallerSessions/Android.bp
+++ b/core/tests/PackageInstallerSessions/Android.bp
@@ -35,7 +35,7 @@
         "frameworks-base-testutils",
         "platform-test-annotations",
         "testng",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: [
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
index 5260835..1fb5f2c 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
@@ -18,7 +18,7 @@
         "platform-test-annotations",
         "platformprotosnano",
         "statsdprotolite",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: ["android.test.runner"],
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index 2b34ee2..7c1ac48 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -32,7 +32,7 @@
     static_libs: [
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
-        "truth-prebuilt",
+        "truth",
     ],
     test_suites: ["general-tests"],
     sdk_version: "test_current",
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 286697c..65af1c6 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -56,7 +56,7 @@
         "ub-uiautomator",
         "platform-test-annotations",
         "platform-compat-test-rules",
-        "truth-prebuilt",
+        "truth",
         "print-test-util-lib",
         "testng",
         "servicestests-utils",
@@ -148,7 +148,7 @@
         "androidx.test.runner",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: [
diff --git a/core/tests/coretests/src/android/app/KeyguardManagerTest.java b/core/tests/coretests/src/android/app/KeyguardManagerTest.java
index 958906c..ed8b288 100644
--- a/core/tests/coretests/src/android/app/KeyguardManagerTest.java
+++ b/core/tests/coretests/src/android/app/KeyguardManagerTest.java
@@ -174,6 +174,22 @@
     }
 
     @Test
+    public void setLock_validatesCredential() {
+        // setLock() should validate the credential before setting it.  Test one example, which is
+        // that PINs must contain only ASCII digits 0-9, i.e. bytes 48-57.  Using bytes 0-9 is
+        // incorrect and should *not* be accepted.
+        byte[] invalidPin = new byte[] { 1, 2, 3, 4 };
+        byte[] validPin = "1234".getBytes();
+
+        assertFalse(mKeyguardManager.setLock(KeyguardManager.PIN, invalidPin, -1, null));
+        assertFalse(mKeyguardManager.isDeviceSecure());
+
+        assertTrue(mKeyguardManager.setLock(KeyguardManager.PIN, validPin, -1, null));
+        assertTrue(mKeyguardManager.isDeviceSecure());
+        assertTrue(mKeyguardManager.setLock(-1, null, KeyguardManager.PIN, validPin));
+    }
+
+    @Test
     public void checkLock_correctCredentials() {
         // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.
         doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage();
diff --git a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
index c9e02f8..33e81c1 100644
--- a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
+++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java
@@ -25,6 +25,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 import static android.app.admin.PasswordMetrics.complexityLevelToMinQuality;
 import static android.app.admin.PasswordMetrics.sanitizeComplexityLevel;
+import static android.app.admin.PasswordMetrics.validateCredential;
 import static android.app.admin.PasswordMetrics.validatePasswordMetrics;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
@@ -41,6 +42,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockscreenCredential;
 import com.android.internal.widget.PasswordValidationError;
 
 import org.junit.Test;
@@ -94,8 +97,7 @@
 
     @Test
     public void testComputeForPassword_metrics() {
-        final PasswordMetrics metrics = PasswordMetrics.computeForPasswordOrPin(
-                "6B~0z1Z3*8A".getBytes(), /* isPin */ false);
+        final PasswordMetrics metrics = metricsForPassword("6B~0z1Z3*8A");
         assertEquals(11, metrics.length);
         assertEquals(4, metrics.letters);
         assertEquals(3, metrics.upperCase);
@@ -133,72 +135,54 @@
 
     @Test
     public void testDetermineComplexity_lowNumeric() {
-        assertEquals(PASSWORD_COMPLEXITY_LOW,
-                PasswordMetrics.computeForPasswordOrPin("1234".getBytes(),
-                        /* isPin */true).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPin("1234").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_lowNumericComplex() {
-        assertEquals(PASSWORD_COMPLEXITY_LOW,
-                PasswordMetrics.computeForPasswordOrPin("124".getBytes(),
-                        /* isPin */ true).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPin("124").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_lowAlphabetic() {
-        assertEquals(PASSWORD_COMPLEXITY_LOW,
-                PasswordMetrics.computeForPasswordOrPin("a!".getBytes(),
-                        /* isPin */ false).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPassword("a!").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_lowAlphanumeric() {
-        assertEquals(PASSWORD_COMPLEXITY_LOW,
-                PasswordMetrics.computeForPasswordOrPin("a!1".getBytes(),
-                        /* isPin */ false).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPassword("a!1").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_mediumNumericComplex() {
-        assertEquals(PASSWORD_COMPLEXITY_MEDIUM,
-                PasswordMetrics.computeForPasswordOrPin("1238".getBytes(),
-                        /* isPin */ true).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPin("1238").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_mediumAlphabetic() {
-        assertEquals(PASSWORD_COMPLEXITY_MEDIUM,
-                PasswordMetrics.computeForPasswordOrPin("ab!c".getBytes(),
-                        /* isPin */ false).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPassword("ab!c").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_mediumAlphanumeric() {
-        assertEquals(PASSWORD_COMPLEXITY_MEDIUM,
-                PasswordMetrics.computeForPasswordOrPin("ab!1".getBytes(),
-                        /* isPin */ false).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPassword("ab!1").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_highNumericComplex() {
-        assertEquals(PASSWORD_COMPLEXITY_HIGH,
-                PasswordMetrics.computeForPasswordOrPin("12389647!".getBytes(),
-                        /* isPin */ true).determineComplexity());
+        assertEquals(PASSWORD_COMPLEXITY_HIGH, metricsForPin("12389647!").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_highAlphabetic() {
         assertEquals(PASSWORD_COMPLEXITY_HIGH,
-                PasswordMetrics.computeForPasswordOrPin("alphabetic!".getBytes(),
-                        /* isPin */ false).determineComplexity());
+                metricsForPassword("alphabetic!").determineComplexity());
     }
 
     @Test
     public void testDetermineComplexity_highAlphanumeric() {
         assertEquals(PASSWORD_COMPLEXITY_HIGH,
-                PasswordMetrics.computeForPasswordOrPin("alphanumeric123!".getBytes(),
-                        /* isPin */ false).determineComplexity());
+                metricsForPassword("alphanumeric123!").determineComplexity());
     }
 
     @Test
@@ -374,8 +358,74 @@
                 PasswordValidationError.NOT_ENOUGH_NON_DIGITS, 1);
     }
 
+    @Test
+    public void testValidateCredential_none() {
+        PasswordMetrics adminMetrics;
+        LockscreenCredential none = LockscreenCredential.createNone();
+
+        adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, none));
+
+        adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PIN);
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, none),
+                PasswordValidationError.WEAK_CREDENTIAL_TYPE, 0);
+    }
+
+    @Test
+    public void testValidateCredential_password() {
+        PasswordMetrics adminMetrics;
+        LockscreenCredential password;
+
+        adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
+        password = LockscreenCredential.createPassword("password");
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password));
+
+        // Test that validateCredential() checks LockscreenCredential#hasInvalidChars().
+        adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
+        password = LockscreenCredential.createPassword("™™™™");
+        assertTrue(password.hasInvalidChars());
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password),
+                PasswordValidationError.CONTAINS_INVALID_CHARACTERS, 0);
+
+        // Test one more case where validateCredential() should reject the password.  Beyond this,
+        // the unit tests for the lower-level method validatePasswordMetrics() should be sufficient.
+        adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
+        adminMetrics.length = 6;
+        password = LockscreenCredential.createPassword("pass");
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password),
+                PasswordValidationError.TOO_SHORT, 6);
+    }
+
+    private LockscreenCredential createPattern(String patternString) {
+        return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
+                patternString.getBytes()));
+    }
+
+    private static PasswordMetrics metricsForPassword(String password) {
+        return PasswordMetrics.computeForCredential(LockscreenCredential.createPassword(password));
+    }
+
+    private static PasswordMetrics metricsForPin(String pin) {
+        return PasswordMetrics.computeForCredential(LockscreenCredential.createPin(pin));
+    }
+
+    @Test
+    public void testValidateCredential_pattern() {
+        PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, createPattern("123")),
+                PasswordValidationError.TOO_SHORT, 4);
+        assertValidationErrors(
+                validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, createPattern("1234")));
+    }
+
     /**
-     * @param expected sequense of validation error codes followed by requirement values, must have
+     * @param expected sequence of validation error codes followed by requirement values, must have
      *                 even number of elements. Empty means no errors.
      */
     private void assertValidationErrors(
diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java
index b37c8fd..bce3f3e 100644
--- a/core/tests/coretests/src/android/view/ViewGroupTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupTest.java
@@ -49,11 +49,11 @@
     public void testDispatchMouseEventsUnderCursor() {
         final Context context = getInstrumentation().getContext();
         final TestView viewGroup = new TestView(context, 0 /* left */, 0 /* top */,
-                200 /* right */, 200 /* bottom */);
+                200 /* right */, 100 /* bottom */);
         final TestView viewA = spy(new TestView(context, 0 /* left */, 0 /* top */,
-                100 /* right */, 200 /* bottom */));
+                100 /* right */, 100 /* bottom */));
         final TestView viewB = spy(new TestView(context, 100 /* left */, 0 /* top */,
-                200 /* right */, 200 /* bottom */));
+                200 /* right */, 100 /* bottom */));
 
         viewGroup.addView(viewA);
         viewGroup.addView(viewB);
@@ -73,10 +73,10 @@
         MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[2];
         coords[0] = new MotionEvent.PointerCoords();
         coords[0].x = 80;
-        coords[0].y = 100;
+        coords[0].y = 50;
         coords[1] = new MotionEvent.PointerCoords();
         coords[1].x = 240;
-        coords[1].y = 100;
+        coords[1].y = 50;
 
         MotionEvent event;
         // Make sure the down event is active with a pointer which coordinate is different from the
@@ -91,6 +91,10 @@
         viewGroup.onResolvePointerIcon(event, 0 /* pointerIndex */);
         verify(viewB).onResolvePointerIcon(event, 0);
 
+        event.setAction(MotionEvent.ACTION_SCROLL);
+        viewGroup.dispatchGenericMotionEvent(event);
+        verify(viewB).dispatchGenericMotionEvent(event);
+
         event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
                 MotionEvent.ACTION_POINTER_DOWN | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT),
                 2 /* pointerCount */, properties, coords, 0 /* metaState */, 0 /* buttonState */,
@@ -102,8 +106,13 @@
         viewGroup.onResolvePointerIcon(event, 1 /* pointerIndex */);
         verify(viewB).onResolvePointerIcon(event, 1);
 
+        event.setAction(MotionEvent.ACTION_SCROLL);
+        viewGroup.dispatchGenericMotionEvent(event);
+        verify(viewB).dispatchGenericMotionEvent(event);
+
         verify(viewA, never()).dispatchTouchEvent(any());
         verify(viewA, never()).onResolvePointerIcon(any(), anyInt());
+        verify(viewA, never()).dispatchGenericMotionEvent(any());
     }
 
     /**
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java b/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java
index a47868d..5692742 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java
@@ -16,52 +16,71 @@
 
 package com.android.internal.widget;
 
-
 import static com.google.common.truth.Truth.assertThat;
 
-import android.test.AndroidTestCase;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 
+@RunWith(AndroidJUnit4.class)
+public class LockscreenCredentialTest {
 
-public class LockscreenCredentialTest extends AndroidTestCase {
+    @Test
+    public void testNoneCredential() {
+        LockscreenCredential none = LockscreenCredential.createNone();
 
-    public void testEmptyCredential() {
-        LockscreenCredential empty = LockscreenCredential.createNone();
+        assertTrue(none.isNone());
+        assertEquals(0, none.size());
+        assertArrayEquals(new byte[0], none.getCredential());
 
-        assertTrue(empty.isNone());
-        assertEquals(0, empty.size());
-        assertNotNull(empty.getCredential());
-
-        assertFalse(empty.isPin());
-        assertFalse(empty.isPassword());
-        assertFalse(empty.isPattern());
+        assertFalse(none.isPin());
+        assertFalse(none.isPassword());
+        assertFalse(none.isPattern());
+        assertFalse(none.hasInvalidChars());
+        none.validateBasicRequirements();
     }
 
+    @Test
     public void testPinCredential() {
         LockscreenCredential pin = LockscreenCredential.createPin("3456");
 
         assertTrue(pin.isPin());
         assertEquals(4, pin.size());
-        assertTrue(Arrays.equals("3456".getBytes(), pin.getCredential()));
+        assertArrayEquals("3456".getBytes(), pin.getCredential());
 
         assertFalse(pin.isNone());
         assertFalse(pin.isPassword());
         assertFalse(pin.isPattern());
+        assertFalse(pin.hasInvalidChars());
+        pin.validateBasicRequirements();
     }
 
+    @Test
     public void testPasswordCredential() {
         LockscreenCredential password = LockscreenCredential.createPassword("password");
 
         assertTrue(password.isPassword());
         assertEquals(8, password.size());
-        assertTrue(Arrays.equals("password".getBytes(), password.getCredential()));
+        assertArrayEquals("password".getBytes(), password.getCredential());
 
         assertFalse(password.isNone());
         assertFalse(password.isPin());
         assertFalse(password.isPattern());
+        assertFalse(password.hasInvalidChars());
+        password.validateBasicRequirements();
     }
 
+    @Test
     public void testPatternCredential() {
         LockscreenCredential pattern = LockscreenCredential.createPattern(Arrays.asList(
                 LockPatternView.Cell.of(0, 0),
@@ -73,13 +92,34 @@
 
         assertTrue(pattern.isPattern());
         assertEquals(5, pattern.size());
-        assertTrue(Arrays.equals("12369".getBytes(), pattern.getCredential()));
+        assertArrayEquals("12369".getBytes(), pattern.getCredential());
 
         assertFalse(pattern.isNone());
         assertFalse(pattern.isPin());
         assertFalse(pattern.isPassword());
+        assertFalse(pattern.hasInvalidChars());
+        pattern.validateBasicRequirements();
     }
 
+    // Constructing a LockscreenCredential with a too-short length, even 0, should not throw an
+    // exception.  This is because LockscreenCredential needs to be able to represent a request to
+    // set a credential that is too short.
+    @Test
+    public void testZeroLengthCredential() {
+        LockscreenCredential credential = LockscreenCredential.createPin("");
+        assertTrue(credential.isPin());
+        assertEquals(0, credential.size());
+
+        credential = createPattern("");
+        assertTrue(credential.isPattern());
+        assertEquals(0, credential.size());
+
+        credential = LockscreenCredential.createPassword("");
+        assertTrue(credential.isPassword());
+        assertEquals(0, credential.size());
+    }
+
+    @Test
     public void testPasswordOrNoneCredential() {
         assertEquals(LockscreenCredential.createNone(),
                 LockscreenCredential.createPasswordOrNone(null));
@@ -89,6 +129,7 @@
                 LockscreenCredential.createPasswordOrNone("abcd"));
     }
 
+    @Test
     public void testPinOrNoneCredential() {
         assertEquals(LockscreenCredential.createNone(),
                 LockscreenCredential.createPinOrNone(null));
@@ -98,6 +139,35 @@
                 LockscreenCredential.createPinOrNone("1357"));
     }
 
+    // Test that passwords containing invalid characters that were incorrectly allowed in
+    // Android 10–14 are still interpreted in the same way, but are not allowed for new passwords.
+    @Test
+    public void testPasswordWithInvalidChars() {
+        // ™ is U+2122, which was truncated to ASCII 0x22 which is double quote.
+        String[] passwords = new String[] { "foo™", "™™™™", "™foo" };
+        String[] equivalentAsciiPasswords = new String[] { "foo\"", "\"\"\"\"", "\"foo" };
+        for (int i = 0; i < passwords.length; i++) {
+            LockscreenCredential credential = LockscreenCredential.createPassword(passwords[i]);
+            assertTrue(credential.hasInvalidChars());
+            assertArrayEquals(equivalentAsciiPasswords[i].getBytes(), credential.getCredential());
+            try {
+                credential.validateBasicRequirements();
+                fail("should not be able to set password with invalid chars");
+            } catch (IllegalArgumentException expected) { }
+        }
+    }
+
+    @Test
+    public void testPinWithInvalidChars() {
+        LockscreenCredential pin = LockscreenCredential.createPin("\n\n\n\n");
+        assertTrue(pin.hasInvalidChars());
+        try {
+            pin.validateBasicRequirements();
+            fail("should not be able to set PIN with invalid chars");
+        } catch (IllegalArgumentException expected) { }
+    }
+
+    @Test
     public void testSanitize() {
         LockscreenCredential password = LockscreenCredential.createPassword("password");
         password.zeroize();
@@ -123,11 +193,16 @@
             fail("Sanitized credential still accessible");
         } catch (IllegalStateException expected) { }
         try {
+            password.hasInvalidChars();
+            fail("Sanitized credential still accessible");
+        } catch (IllegalStateException expected) { }
+        try {
             password.getCredential();
             fail("Sanitized credential still accessible");
         } catch (IllegalStateException expected) { }
     }
 
+    @Test
     public void testEquals() {
         assertEquals(LockscreenCredential.createNone(), LockscreenCredential.createNone());
         assertEquals(LockscreenCredential.createPassword("1234"),
@@ -136,34 +211,40 @@
                 LockscreenCredential.createPin("4321"));
         assertEquals(createPattern("1234"), createPattern("1234"));
 
-        assertNotSame(LockscreenCredential.createPassword("1234"),
+        assertNotEquals(LockscreenCredential.createPassword("1234"),
                 LockscreenCredential.createNone());
-        assertNotSame(LockscreenCredential.createPassword("1234"),
+        assertNotEquals(LockscreenCredential.createPassword("1234"),
                 LockscreenCredential.createPassword("4321"));
-        assertNotSame(LockscreenCredential.createPassword("1234"),
+        assertNotEquals(LockscreenCredential.createPassword("1234"),
                 createPattern("1234"));
-        assertNotSame(LockscreenCredential.createPassword("1234"),
+        assertNotEquals(LockscreenCredential.createPassword("1234"),
                 LockscreenCredential.createPin("1234"));
 
-        assertNotSame(LockscreenCredential.createPin("1111"),
+        assertNotEquals(LockscreenCredential.createPin("1111"),
                 LockscreenCredential.createNone());
-        assertNotSame(LockscreenCredential.createPin("1111"),
+        assertNotEquals(LockscreenCredential.createPin("1111"),
                 LockscreenCredential.createPin("2222"));
-        assertNotSame(LockscreenCredential.createPin("1111"),
+        assertNotEquals(LockscreenCredential.createPin("1111"),
                 createPattern("1111"));
-        assertNotSame(LockscreenCredential.createPin("1111"),
+        assertNotEquals(LockscreenCredential.createPin("1111"),
                 LockscreenCredential.createPassword("1111"));
 
-        assertNotSame(createPattern("5678"),
+        assertNotEquals(createPattern("5678"),
                 LockscreenCredential.createNone());
-        assertNotSame(createPattern("5678"),
+        assertNotEquals(createPattern("5678"),
                 createPattern("1234"));
-        assertNotSame(createPattern("5678"),
+        assertNotEquals(createPattern("5678"),
                 LockscreenCredential.createPassword("5678"));
-        assertNotSame(createPattern("5678"),
+        assertNotEquals(createPattern("5678"),
                 LockscreenCredential.createPin("5678"));
+
+        // Test that mHasInvalidChars is compared.  To do this, compare two passwords that map to
+        // the same byte[] (due to the truncation bug) but different values of mHasInvalidChars.
+        assertNotEquals(LockscreenCredential.createPassword("™™™™"),
+                LockscreenCredential.createPassword("\"\"\"\""));
     }
 
+    @Test
     public void testDuplicate() {
         LockscreenCredential credential;
 
@@ -175,8 +256,13 @@
         assertEquals(credential, credential.duplicate());
         credential = createPattern("5678");
         assertEquals(credential, credential.duplicate());
+
+        // Test that mHasInvalidChars is duplicated.
+        credential = LockscreenCredential.createPassword("™™™™");
+        assertEquals(credential, credential.duplicate());
     }
 
+    @Test
     public void testPasswordToHistoryHash() {
         String password = "1234";
         LockscreenCredential credential = LockscreenCredential.createPassword(password);
@@ -193,6 +279,7 @@
                 .isEqualTo(expectedHash);
     }
 
+    @Test
     public void testPasswordToHistoryHashInvalidInput() {
         String password = "1234";
         LockscreenCredential credential = LockscreenCredential.createPassword(password);
@@ -221,6 +308,7 @@
                 .isNull();
     }
 
+    @Test
     public void testLegacyPasswordToHash() {
         String password = "1234";
         String salt = "6d5331dd120077a0";
@@ -233,6 +321,7 @@
                 .isEqualTo(expectedHash);
     }
 
+    @Test
     public void testLegacyPasswordToHashInvalidInput() {
         String password = "1234";
         String salt = "6d5331dd120077a0";
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
index 3d04937..5f6eaf9 100644
--- a/core/tests/hdmitests/Android.bp
+++ b/core/tests/hdmitests/Android.bp
@@ -30,7 +30,7 @@
         "frameworks-base-testutils",
         "guava-android-testlib",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: ["android.test.runner"],
     platform_apis: true,
diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp
index 96811be..a2dd914 100644
--- a/core/tests/mockingcoretests/Android.bp
+++ b/core/tests/mockingcoretests/Android.bp
@@ -38,7 +38,7 @@
         "androidx.test.ext.junit",
         "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "ub-uiautomator",
     ],
diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp
index c74600b..f81be49 100644
--- a/core/tests/nfctests/Android.bp
+++ b/core/tests/nfctests/Android.bp
@@ -27,7 +27,7 @@
         "androidx.test.ext.junit",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "android.test.runner",
diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp
index 063c569..931eac5 100644
--- a/core/tests/overlaytests/device_self_targeting/Android.bp
+++ b/core/tests/overlaytests/device_self_targeting/Android.bp
@@ -30,7 +30,7 @@
         "androidx.test.runner",
         "androidx.test.ext.junit",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
 
     optimize: {
diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp
index bc3dd81..4e24cd5 100644
--- a/core/tests/privacytests/Android.bp
+++ b/core/tests/privacytests/Android.bp
@@ -14,7 +14,7 @@
         "junit",
         "rappor-tests",
         "androidx.test.rules",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: ["android.test.runner"],
     platform_apis: true,
diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp
index 3798da5..580e73c 100644
--- a/core/tests/utiltests/Android.bp
+++ b/core/tests/utiltests/Android.bp
@@ -33,7 +33,7 @@
         "frameworks-base-testutils",
         "mockito-target-minus-junit4",
         "androidx.test.ext.junit",
-        "truth-prebuilt",
+        "truth",
         "servicestests-utils",
     ],
 
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index 8f32f0e..3328708 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -39,7 +39,7 @@
     java_resource_dirs: ["tests/res"],
     java_resources: [":error_prone_android_framework_testdata"],
     static_libs: [
-        "truth-prebuilt",
+        "truth",
         "kxml2-2.3.0",
         "compile-testing-prebuilt",
         "error_prone_android_framework_lib",
diff --git a/keystore/aaid/aidl/Android.bp b/keystore/aaid/aidl/Android.bp
new file mode 100644
index 0000000..97acfb4
--- /dev/null
+++ b/keystore/aaid/aidl/Android.bp
@@ -0,0 +1,31 @@
+// Copyright 2020, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.security.aaid_aidl",
+    srcs: ["android/security/keystore/*.aidl"],
+    unstable: true,
+    backend: {
+        rust: {
+            enabled: true,
+        },
+        cpp: {
+            enabled: true,
+        },
+    },
+}
diff --git a/keystore/aaid/aidl/android/security/keystore/IKeyAttestationApplicationIdProvider.aidl b/keystore/aaid/aidl/android/security/keystore/IKeyAttestationApplicationIdProvider.aidl
new file mode 100644
index 0000000..c360cb8
--- /dev/null
+++ b/keystore/aaid/aidl/android/security/keystore/IKeyAttestationApplicationIdProvider.aidl
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeyAttestationApplicationId;
+
+/** @hide */
+interface IKeyAttestationApplicationIdProvider {
+    /**
+     * Provides information describing the possible applications identified by a UID.
+     * @hide
+     */
+    KeyAttestationApplicationId getKeyAttestationApplicationId(int uid);
+}
diff --git a/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl b/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl
new file mode 100644
index 0000000..c33e830
--- /dev/null
+++ b/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.KeyAttestationPackageInfo;
+
+/**
+ * @hide
+ * The information aggregated by this parcelable is used by keystore to identify a caller of the
+ * keystore API toward a remote party. It aggregates multiple PackageInfos because keystore
+ * can only determine a caller by uid granularity, and a uid can be shared by multiple packages.
+ * The remote party must decide if it trusts all of the packages enough to consider the
+ * confidentiality of the key material in question intact.
+ */
+parcelable KeyAttestationApplicationId {
+    KeyAttestationPackageInfo[] packageInfos;
+}
diff --git a/keystore/aaid/aidl/android/security/keystore/KeyAttestationPackageInfo.aidl b/keystore/aaid/aidl/android/security/keystore/KeyAttestationPackageInfo.aidl
new file mode 100644
index 0000000..5f647d0
--- /dev/null
+++ b/keystore/aaid/aidl/android/security/keystore/KeyAttestationPackageInfo.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.security.keystore.Signature;
+
+/**
+ * @hide
+ * This parcelable constitutes and excerpt from the PackageManager's PackageInfo for the purpose of
+ * key attestation. It is part of the KeyAttestationApplicationId, which is used by
+ * keystore to identify the caller of the keystore API towards a remote party.
+ */
+parcelable KeyAttestationPackageInfo {
+    String packageName;
+
+    long versionCode;
+
+    Signature[] signatures;
+}
diff --git a/keystore/aaid/aidl/android/security/keystore/Signature.aidl b/keystore/aaid/aidl/android/security/keystore/Signature.aidl
new file mode 100644
index 0000000..800499a
--- /dev/null
+++ b/keystore/aaid/aidl/android/security/keystore/Signature.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+/**
+ * @hide
+ * Represents a signature data read from the package file. Extracted from from the PackageManager's
+ * PackageInfo for the purpose of key attestation. It is part of the KeyAttestationPackageInfo,
+ * which is used by keystore to identify the caller of the keystore API towards a remote party.
+ */
+parcelable Signature {
+    /**
+     * Represents signing certificate data associated with application package, signatures are
+     * expected to be a hex-encoded ASCII string representing valid X509 certificate.
+     */
+    byte[] data;
+}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 0f3488b..31c2eb2 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -28,8 +28,8 @@
 import android.util.Log;
 
 /**
- * @hide This is the client side for IKeystoreUserManager AIDL.
- * It shall only be used by the LockSettingsService.
+ * @hide This is the client side for IKeystoreMaintenance AIDL.
+ * It is used mainly by LockSettingsService.
  */
 public class AndroidKeyStoreMaintenance {
     private static final String TAG = "AndroidKeyStoreMaintenance";
@@ -66,7 +66,7 @@
     }
 
     /**
-     * Informs Keystore 2.0 about removing a usergit mer
+     * Informs Keystore 2.0 about removing a user
      *
      * @param userId - Android user id of the user being removed
      * @return 0 if successful or a {@code ResponseCode}
@@ -91,7 +91,7 @@
      *
      * @param userId   - Android user id of the user
      * @param password - a secret derived from the synthetic password provided by the
-     *                 LockSettingService
+     *                 LockSettingsService
      * @return 0 if successful or a {@code ResponseCode}
      * @hide
      */
@@ -110,7 +110,7 @@
     }
 
     /**
-     * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to
+     * Informs Keystore 2.0 that an app was uninstalled and the corresponding namespace is to
      * be cleared.
      */
     public static int clearNamespace(@Domain int domain, long namespace) {
@@ -172,10 +172,10 @@
      *                    namespace.
      *
      * @return * 0 on success
-     *         * KEY_NOT_FOUND if the source did not exists.
+     *         * KEY_NOT_FOUND if the source did not exist.
      *         * PERMISSION_DENIED if any of the required permissions was missing.
      *         * INVALID_ARGUMENT if the destination was occupied or any domain value other than
-     *                   the allowed once were specified.
+     *                   the allowed ones was specified.
      *         * SYSTEM_ERROR if an unexpected error occurred.
      */
     public static int migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination) {
diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
index b6e743a..ed2ff2d 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/Android.bp
+++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
@@ -37,7 +37,7 @@
         "androidx.test.rules",
         "androidx.test.ext.junit",
         "mockito-target-extended-minus-junit4",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "platform-test-annotations",
     ],
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index b6696c7..82bcec4 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -43,7 +43,7 @@
         "flickerlib",
         "flickerlib-apphelpers",
         "flickerlib-helpers",
-        "truth-prebuilt",
+        "truth",
         "app-helpers-core",
         "launcher-helper-lib",
         "launcher-aosp-tapl",
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 38e9f39..34ca1d0 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -44,7 +44,7 @@
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
         "mockito-target-extended-minus-junit4",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "platform-test-annotations",
         "servicestests-utils",
diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp
index 2d79090..c256e2f 100644
--- a/libs/dream/lowlight/tests/Android.bp
+++ b/libs/dream/lowlight/tests/Android.bp
@@ -33,7 +33,7 @@
         "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
         "testables",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "android.test.mock",
diff --git a/libs/hwui/api/current.txt b/libs/hwui/api/current.txt
index c396a20..7940821 100644
--- a/libs/hwui/api/current.txt
+++ b/libs/hwui/api/current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.graphics {
 
   public class ColorMatrix {
diff --git a/libs/hwui/api/module-lib-current.txt b/libs/hwui/api/module-lib-current.txt
index d802177..14191eb 100644
--- a/libs/hwui/api/module-lib-current.txt
+++ b/libs/hwui/api/module-lib-current.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/libs/hwui/api/module-lib-removed.txt b/libs/hwui/api/module-lib-removed.txt
index d802177..14191eb 100644
--- a/libs/hwui/api/module-lib-removed.txt
+++ b/libs/hwui/api/module-lib-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/libs/hwui/api/removed.txt b/libs/hwui/api/removed.txt
index d802177..14191eb 100644
--- a/libs/hwui/api/removed.txt
+++ b/libs/hwui/api/removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/libs/hwui/api/system-current.txt b/libs/hwui/api/system-current.txt
index d802177..14191eb 100644
--- a/libs/hwui/api/system-current.txt
+++ b/libs/hwui/api/system-current.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/libs/hwui/api/system-removed.txt b/libs/hwui/api/system-removed.txt
index d802177..14191eb 100644
--- a/libs/hwui/api/system-removed.txt
+++ b/libs/hwui/api/system-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/libs/securebox/tests/Android.bp b/libs/securebox/tests/Android.bp
index 7df546a..80b501d 100644
--- a/libs/securebox/tests/Android.bp
+++ b/libs/securebox/tests/Android.bp
@@ -32,7 +32,7 @@
         "platform-test-annotations",
         "testables",
         "testng",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "android.test.mock",
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index b0cdb05..1d66868 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -875,18 +875,7 @@
         /**
          * Sets the attribute describing what is the intended use of the audio signal,
          * such as alarm or ringtone.
-         * @param usage one of {@link AttributeSdkUsage#USAGE_UNKNOWN},
-         *     {@link AttributeSdkUsage#USAGE_MEDIA},
-         *     {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION},
-         *     {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION_SIGNALLING},
-         *     {@link AttributeSdkUsage#USAGE_ALARM}, {@link AudioAttributes#USAGE_NOTIFICATION},
-         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_RINGTONE},
-         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_EVENT},
-         *     {@link AttributeSdkUsage#USAGE_ASSISTANT},
-         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_ACCESSIBILITY},
-         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE},
-         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_SONIFICATION},
-         *     {@link AttributeSdkUsage#USAGE_GAME}.
+         * @param usage the usage to set.
          * @return the same Builder instance.
          */
         public Builder setUsage(@AttributeSdkUsage int usage) {
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index a311296..ceb3858 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1284,8 +1284,7 @@
          *    {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}.
          *    <p> For a valid {@link AudioTrack} channel position mask,
          *    the following conditions apply:
-         *    <br> (1) at most {@link AudioSystem#OUT_CHANNEL_COUNT_MAX} channel positions may be
-         *    used;
+         *    <br> (1) at most eight channel positions may be used;
          *    <br> (2) right/left pairs should be matched.
          *    <p> For input or {@link AudioRecord}, the mask should be
          *    {@link AudioFormat#CHANNEL_IN_MONO} or
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ab2a22b..0dea2c8 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1485,8 +1485,7 @@
      * Returns the volume group id associated to the given {@link AudioAttributes}.
      *
      * @param attributes The {@link AudioAttributes} to consider.
-     * @return {@link android.media.audiopolicy.AudioVolumeGroup} id supporting the given
-     * {@link AudioAttributes} if found,
+     * @return audio volume group id supporting the given {@link AudioAttributes} if found,
      * {@code android.media.audiopolicy.AudioVolumeGroup.DEFAULT_VOLUME_GROUP} otherwise.
      */
     public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
@@ -1601,7 +1600,7 @@
      * <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
      * the volume group id supporting the given {@link AudioAttributes}.
      *
-     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
+     * @param groupId of the audio volume group to consider.
      * @param direction The direction to adjust the volume. One of
      *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
      *            {@link #ADJUST_SAME}.
@@ -1645,8 +1644,8 @@
      * <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
      * the volume group id supporting the given {@link AudioAttributes}.
      *
-     * @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
-     * @return The mute state for the given {@link android.media.audiopolicy.AudioVolumeGroup} id.
+     * @param groupId of the audio volume group to consider.
+     * @return The mute state for the given audio volume group id.
      * @see #adjustVolumeGroupVolume(int, int, int)
      */
     public boolean isVolumeGroupMuted(int groupId) {
diff --git a/media/java/android/media/AudioMetadata.java b/media/java/android/media/AudioMetadata.java
index 0f962f9..4e61549 100644
--- a/media/java/android/media/AudioMetadata.java
+++ b/media/java/android/media/AudioMetadata.java
@@ -226,16 +226,15 @@
          *
          * An Integer value representing presentation content classifier.
          *
-         * @see AudioPresentation.ContentClassifier
-         * One of {@link AudioPresentation#CONTENT_UNKNOWN},
-         *     {@link AudioPresentation#CONTENT_MAIN},
-         *     {@link AudioPresentation#CONTENT_MUSIC_AND_EFFECTS},
-         *     {@link AudioPresentation#CONTENT_VISUALLY_IMPAIRED},
-         *     {@link AudioPresentation#CONTENT_HEARING_IMPAIRED},
-         *     {@link AudioPresentation#CONTENT_DIALOG},
-         *     {@link AudioPresentation#CONTENT_COMMENTARY},
-         *     {@link AudioPresentation#CONTENT_EMERGENCY},
-         *     {@link AudioPresentation#CONTENT_VOICEOVER}.
+         * @see AudioPresentation#CONTENT_UNKNOWN
+         * @see AudioPresentation#CONTENT_MAIN
+         * @see AudioPresentation#CONTENT_MUSIC_AND_EFFECTS
+         * @see AudioPresentation#CONTENT_VISUALLY_IMPAIRED
+         * @see AudioPresentation#CONTENT_HEARING_IMPAIRED
+         * @see AudioPresentation#CONTENT_DIALOG
+         * @see AudioPresentation#CONTENT_COMMENTARY
+         * @see AudioPresentation#CONTENT_EMERGENCY
+         * @see AudioPresentation#CONTENT_VOICEOVER
          */
         @NonNull public static final Key<Integer> KEY_PRESENTATION_CONTENT_CLASSIFIER =
                 createKey("presentation-content-classifier", Integer.class);
diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS
index cc9be9c..880ec8f 100644
--- a/media/java/android/media/projection/OWNERS
+++ b/media/java/android/media/projection/OWNERS
@@ -4,3 +4,4 @@
 santoscordon@google.com
 chaviw@google.com
 nmusgrave@google.com
+dakinola@google.com
diff --git a/media/java/android/media/tv/SectionRequest.java b/media/java/android/media/tv/SectionRequest.java
index 078e832..ec0d7f7 100644
--- a/media/java/android/media/tv/SectionRequest.java
+++ b/media/java/android/media/tv/SectionRequest.java
@@ -81,7 +81,7 @@
     /**
      * Gets the version number of requested session. If it is null, value will be -1.
      * <p>The consistency of version numbers between request and response depends on
-     * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+     * {@link BroadcastInfoRequest#getOption()}. If the request has RequestOption value
      * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
      * different from the version of the request. Otherwise, response with a different version from
      * its request will be considered invalid.
diff --git a/media/java/android/media/tv/SectionResponse.java b/media/java/android/media/tv/SectionResponse.java
index f38ea9d..10333fe 100644
--- a/media/java/android/media/tv/SectionResponse.java
+++ b/media/java/android/media/tv/SectionResponse.java
@@ -76,7 +76,7 @@
     /**
      * Gets the Version number of requested session. If it is null, value will be -1.
      * <p>The consistency of version numbers between request and response depends on
-     * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+     * {@link BroadcastInfoRequest#getOption()}. If the request has RequestOption value
      * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
      * different from the version of the request. Otherwise, response with a different version from
      * its request will be considered invalid.
diff --git a/media/java/android/media/tv/TableRequest.java b/media/java/android/media/tv/TableRequest.java
index d9587f6..06df07f 100644
--- a/media/java/android/media/tv/TableRequest.java
+++ b/media/java/android/media/tv/TableRequest.java
@@ -129,7 +129,7 @@
     /**
      * Gets the version number of requested table. If it is null, value will be -1.
      * <p>The consistency of version numbers between request and response depends on
-     * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+     * {@link BroadcastInfoRequest#getOption()}. If the request has RequestOption value
      * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
      * different from the version of the request. Otherwise, response with a different version from
      * its request will be considered invalid.
diff --git a/media/java/android/media/tv/TableResponse.java b/media/java/android/media/tv/TableResponse.java
index c4fc26e..1daf452 100644
--- a/media/java/android/media/tv/TableResponse.java
+++ b/media/java/android/media/tv/TableResponse.java
@@ -269,7 +269,7 @@
     /**
      * Gets the version number of requested table. If it is null, value will be -1.
      * <p>The consistency of version numbers between request and response depends on
-     * {@link BroadcastInfoRequest.RequestOption}. If the request has RequestOption value
+     * {@link BroadcastInfoRequest#getOption()}. If the request has RequestOption value
      * REQUEST_OPTION_AUTO_UPDATE, then the response may be set to the latest version which may be
      * different from the version of the request. Otherwise, response with a different version from
      * its request will be considered invalid.
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index c616b84f..1c25080 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -38,6 +38,8 @@
 #include <mediadrm/IDrmMetricsConsumer.h>
 #include <mediadrm/IDrm.h>
 #include <utils/Vector.h>
+#include <map>
+#include <string>
 
 using ::android::os::PersistableBundle;
 namespace drm = ::android::hardware::drm;
@@ -193,6 +195,11 @@
     jclass classId;
 };
 
+struct DrmExceptionFields {
+    jmethodID init;
+    jclass classId;
+};
+
 struct fields_t {
     jfieldID context;
     jmethodID post_event;
@@ -215,6 +222,7 @@
     jclass parcelCreatorClassId;
     KeyStatusFields keyStatus;
     LogMessageFields logMessage;
+    std::map<std::string, DrmExceptionFields> exceptionCtors;
 };
 
 static fields_t gFields;
@@ -245,18 +253,32 @@
     return arrayList;
 }
 
-int drmThrowException(JNIEnv* env, const char *className, const DrmStatus &err, const char *msg) {
+void resolveDrmExceptionCtor(JNIEnv *env, const char *className) {
+    jclass clazz;
+    jmethodID init;
+    FIND_CLASS(clazz, className);
+    GET_METHOD_ID(init, clazz, "<init>", "(Ljava/lang/String;III)V");
+    gFields.exceptionCtors[std::string(className)] = {
+        .init = init,
+        .classId = static_cast<jclass>(env->NewGlobalRef(clazz))
+        };
+}
+
+void drmThrowException(JNIEnv* env, const char *className, const DrmStatus &err, const char *msg) {
     using namespace android::jnihelp;
-    jstring _detailMessage = CreateExceptionMsg(env, msg);
-    int _status = ThrowException(env, className, "(Ljava/lang/String;III)V",
-                                 _detailMessage,
-                                 err.getCdmErr(),
-                                 err.getOemErr(),
-                                 err.getContext());
-    if (_detailMessage != NULL) {
-        env->DeleteLocalRef(_detailMessage);
+
+    if (gFields.exceptionCtors.count(std::string(className)) == 0) {
+        jniThrowException(env, className, msg);
+    } else {
+        jstring _detailMessage = CreateExceptionMsg(env, msg);
+        jobject exception = env->NewObject(gFields.exceptionCtors[std::string(className)].classId,
+            gFields.exceptionCtors[std::string(className)].init, _detailMessage,
+            err.getCdmErr(), err.getOemErr(), err.getContext());
+        env->Throw(static_cast<jthrowable>(exception));
+        if (_detailMessage != NULL) {
+            env->DeleteLocalRef(_detailMessage);
+        }
     }
-    return _status;
 }
 }  // namespace anonymous
 
@@ -952,6 +974,10 @@
     FIND_CLASS(clazz, "android/media/MediaDrm$LogMessage");
     gFields.logMessage.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
     GET_METHOD_ID(gFields.logMessage.init, clazz, "<init>", "(JILjava/lang/String;)V");
+
+    resolveDrmExceptionCtor(env, "android/media/NotProvisionedException");
+    resolveDrmExceptionCtor(env, "android/media/ResourceBusyException");
+    resolveDrmExceptionCtor(env, "android/media/DeniedByServerException");
 }
 
 static void android_media_MediaDrm_native_setup(
@@ -2192,4 +2218,4 @@
 int register_android_media_Drm(JNIEnv *env) {
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaDrm", gMethods, NELEM(gMethods));
-}
+}
\ No newline at end of file
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index 4cccf89..61b18c8 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -24,7 +24,7 @@
         "compatibility-device-util-axt",
         "mockito-target-minus-junit4",
         "testng",
-        "truth-prebuilt",
+        "truth",
     ],
     test_suites: ["general-tests"],
     platform_apis: true,
diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp
index e313c46..48cd8b6 100644
--- a/media/tests/projection/Android.bp
+++ b/media/tests/projection/Android.bp
@@ -30,7 +30,7 @@
         "platform-test-annotations",
         "testng",
         "testables",
-        "truth-prebuilt",
+        "truth",
         "platform-compat-test-rules",
     ],
 
diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp
index 633f186..86c62ef 100644
--- a/packages/ExternalStorageProvider/tests/Android.bp
+++ b/packages/ExternalStorageProvider/tests/Android.bp
@@ -25,7 +25,7 @@
     static_libs: [
         "androidx.test.rules",
         "mockito-target",
-        "truth-prebuilt",
+        "truth",
     ],
 
     certificate: "platform",
diff --git a/packages/FusedLocation/Android.bp b/packages/FusedLocation/Android.bp
index 64b4c54..61a8270 100644
--- a/packages/FusedLocation/Android.bp
+++ b/packages/FusedLocation/Android.bp
@@ -47,7 +47,7 @@
     test_config: "test/AndroidTest.xml",
     srcs: [
         "test/src/**/*.java",
-        "src/**/*.java",  // include real sources because we're forced to test this directly
+        "src/**/*.java", // include real sources because we're forced to test this directly
     ],
     libs: [
         "android.test.base",
@@ -60,9 +60,9 @@
         "androidx.test.ext.junit",
         "androidx.test.ext.truth",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
     platform_apis: true,
     certificate: "platform",
-    test_suites: ["device-tests"]
+    test_suites: ["device-tests"],
 }
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index 2c1e1c2..5622d9d 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -30,7 +30,7 @@
         "androidx.compose.ui_ui-test-junit4",
         "androidx.compose.ui_ui-test-manifest",
         "mockito",
-        "truth-prebuilt",
+        "truth",
     ],
     kotlincflags: [
         "-Xjvm-default=all",
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index ff3eeec..bb57e25 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -49,7 +49,7 @@
         "androidx.test.rules",
         "androidx.test.espresso.core",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
         "SettingsLibDeviceStateRotationLock",
         "SettingsLibSettingsSpinner",
         "SettingsLibUsageProgressBarPreference",
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 5c55a43..ba2e57a 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -64,6 +64,6 @@
     libs: [
         "Robolectric_all-target",
         "mockito-robolectric-prebuilt",
-        "truth-prebuilt",
+        "truth",
     ],
 }
diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp
index a4558f1..0c96f20 100644
--- a/packages/SettingsLib/tests/unit/Android.bp
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -30,6 +30,6 @@
         "SettingsLib",
         "androidx.test.ext.junit",
         "androidx.test.runner",
-        "truth-prebuilt",
+        "truth",
     ],
 }
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 346462d..c7e804c 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -60,7 +60,7 @@
         "SettingsLibDeviceStateRotationLock",
         "SettingsLibDisplayUtils",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "android.test.base",
diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
index 5ade971..86ae581 100644
--- a/packages/SettingsProvider/OWNERS
+++ b/packages/SettingsProvider/OWNERS
@@ -1,5 +1 @@
-hackbod@android.com
-hackbod@google.com
-narayan@google.com
-svetoslavganov@google.com
 include /PACKAGE_MANAGER_OWNERS
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 3efb41d..cf26937 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -163,12 +163,10 @@
         Settings.Secure.CHARGING_VIBRATION_ENABLED,
         Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS,
         Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS,
-        Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
         Settings.Secure.UI_NIGHT_MODE,
         Settings.Secure.UI_NIGHT_MODE_CUSTOM_TYPE,
         Settings.Secure.DARK_THEME_CUSTOM_START_TIME,
         Settings.Secure.DARK_THEME_CUSTOM_END_TIME,
-        Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
         Settings.Secure.SKIP_DIRECTION,
         Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
         Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index f6c2f69..f78f202 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -242,9 +242,7 @@
                 Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(Secure.USER_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
-        VALIDATORS.put(Secure.TRUST_AGENTS_EXTEND_UNLOCK, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, JSON_OBJECT_VALIDATOR);
-        VALIDATORS.put(Secure.LOCK_SCREEN_WHEN_TRUST_LOST, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SKIP_GESTURE, BOOLEAN_VALIDATOR);
         /*
          * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b404465..b19d349 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -961,7 +961,6 @@
                         lockPatternUtils.setOwnerInfo(value, userId);
                         break;
                     case KEY_LOCK_SETTINGS_VISIBLE_PATTERN_ENABLED:
-                        lockPatternUtils.reportPatternWasChosen(userId);
                         lockPatternUtils.setVisiblePatternEnabled("1".equals(value), userId);
                         break;
                     case KEY_LOCK_SETTINGS_POWER_BUTTON_INSTANTLY_LOCKS:
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index a50b182..8ca925b 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -354,7 +354,7 @@
         "hamcrest-library",
         "androidx.test.rules",
         "testables",
-        "truth-prebuilt",
+        "truth",
         "monet",
         "dagger2",
         "jsr330",
@@ -461,7 +461,7 @@
         "android.test.runner",
         "android.test.base",
         "android.test.mock",
-        "truth-prebuilt",
+        "truth",
     ],
 
     upstream: true,
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
index 1757dda..17db1ac 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -31,7 +31,7 @@
         "androidx.test.ext.junit",
         "compatibility-device-util-axt",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
     ],
     srcs: [
         "src/**/*.java",
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index 155dc1a..18f78314 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -49,7 +49,7 @@
         "androidx.test.core",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
     resource_dirs: ["test/res"],
     certificate: "platform",
diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp
index b781602..0244c0f 100644
--- a/packages/overlays/tests/Android.bp
+++ b/packages/overlays/tests/Android.bp
@@ -34,7 +34,7 @@
         "androidx.test.rules",
         "androidx.test.espresso.core",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
     dxflags: ["--multi-dex"],
 }
diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS
new file mode 100644
index 0000000..c06b3b9
--- /dev/null
+++ b/ravenwood/OWNERS
@@ -0,0 +1,3 @@
+jsharkey@google.com
+omakoto@google.com
+jaggies@google.com
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 4e412bb..9ac30f3 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -180,6 +180,7 @@
         "android.hidl.manager-V1.2-java",
         "cbor-java",
         "icu4j_calendar_astronomer",
+        "android.security.aaid_aidl-java",
         "netd-client",
         "overlayable_policy_aidl-java",
         "SurfaceFlingerProperties",
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d94f4f2..5b496f4 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import static android.os.Flags.stateOfHealthPublic;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import static com.android.server.health.Utils.copyV1Battery;
 
@@ -27,7 +28,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.database.ContentObserver;
 import android.hardware.health.HealthInfo;
 import android.hardware.health.V2_1.BatteryCapacityLevel;
@@ -1316,10 +1316,14 @@
         @Override
         public int getProperty(int id, final BatteryProperty prop) throws RemoteException {
             switch (id) {
+                case BatteryManager.BATTERY_PROPERTY_STATE_OF_HEALTH:
+                    if (stateOfHealthPublic()) {
+                        break;
+                    }
+
                 case BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE:
                 case BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE:
                 case BatteryManager.BATTERY_PROPERTY_CHARGING_POLICY:
-                case BatteryManager.BATTERY_PROPERTY_STATE_OF_HEALTH:
                     mContext.enforceCallingPermission(
                             android.Manifest.permission.BATTERY_STATS, null);
                     break;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index f4f5c95..d256aea 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -580,7 +580,6 @@
                      PackageHealthObserverImpact.USER_IMPACT_LEVEL_10,
                      PackageHealthObserverImpact.USER_IMPACT_LEVEL_30,
                      PackageHealthObserverImpact.USER_IMPACT_LEVEL_50,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_60,
                      PackageHealthObserverImpact.USER_IMPACT_LEVEL_70,
                      PackageHealthObserverImpact.USER_IMPACT_LEVEL_100})
     public @interface PackageHealthObserverImpact {
@@ -591,7 +590,6 @@
         /* Actions having medium user impact, user of a device will likely notice. */
         int USER_IMPACT_LEVEL_30 = 30;
         int USER_IMPACT_LEVEL_50 = 50;
-        int USER_IMPACT_LEVEL_60 = 60;
         int USER_IMPACT_LEVEL_70 = 70;
         /* Action has high user impact, a last resort, user of a device will be very frustrated. */
         int USER_IMPACT_LEVEL_100 = 100;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f532122c1..8da9473 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1241,11 +1241,10 @@
             killProcessGroup = true;
         }
         if (killProcessGroup) {
-            if (async) {
-                ProcessList.killProcessGroup(uid, mPid);
-            } else {
+            if (!async) {
                 Process.sendSignalToProcessGroup(uid, mPid, OsConstants.SIGKILL);
             }
+            ProcessList.killProcessGroup(uid, mPid);
         }
     }
 
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index b890bbd..eae417e 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1845,7 +1845,7 @@
     private void parseListenForTickles(TypedXmlPullParser parser) {
         int userId = 0;
         try {
-            parser.getAttributeInt(null, XML_ATTR_USER);
+            userId = parser.getAttributeInt(null, XML_ATTR_USER);
         } catch (XmlPullParserException e) {
             Slog.e(TAG, "error parsing the user for listen-for-tickles", e);
         }
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index 46f486d..f572845 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -311,7 +311,7 @@
 
     @Nullable
     private static synchronized IGateKeeperService getGatekeeperService() {
-        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
+        final IBinder service = ServiceManager.waitForService(Context.GATEKEEPER_SERVICE);
         if (service == null) {
             Slog.e(TAG, "Unable to acquire GateKeeperService");
             return null;
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 0a02c49..09d0bc7 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -115,7 +115,6 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.EventLog;
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Slog;
@@ -347,17 +346,17 @@
 
         @Override
         public void onUserStarting(@NonNull TargetUser user) {
-            mLockSettingsService.onStartUser(user.getUserIdentifier());
+            mLockSettingsService.onUserStarting(user.getUserIdentifier());
         }
 
         @Override
         public void onUserUnlocking(@NonNull TargetUser user) {
-            mLockSettingsService.onUnlockUser(user.getUserIdentifier());
+            mLockSettingsService.onUserUnlocking(user.getUserIdentifier());
         }
 
         @Override
         public void onUserStopped(@NonNull TargetUser user) {
-            mLockSettingsService.onCleanupUser(user.getUserIdentifier());
+            mLockSettingsService.onUserStopped(user.getUserIdentifier());
         }
     }
 
@@ -779,7 +778,7 @@
     }
 
     @VisibleForTesting
-    void onCleanupUser(int userId) {
+    void onUserStopped(int userId) {
         hideEncryptionNotification(new UserHandle(userId));
         // User is stopped with its CE key evicted. Restore strong auth requirement to the default
         // flags after boot since stopping and restarting a user later is equivalent to rebooting
@@ -791,7 +790,7 @@
         }
     }
 
-    private void onStartUser(final int userId) {
+    private void onUserStarting(final int userId) {
         maybeShowEncryptionNotificationForUser(userId, "user started");
     }
 
@@ -827,7 +826,7 @@
         }
     }
 
-    private void onUnlockUser(final int userId) {
+    private void onUserUnlocking(final int userId) {
         // Perform tasks which require locks in LSS on a handler, as we are callbacks from
         // ActivityManager.unlockUser()
         mHandler.post(new Runnable() {
@@ -861,15 +860,11 @@
 
     @Override // binder interface
     public void systemReady() {
-        if (mContext.checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
-            EventLog.writeEvent(0x534e4554, "28251513", getCallingUid(), "");  // SafetyNet
-        }
         checkWritePermission();
 
         mHasSecureLockScreen = mContext.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
         migrateOldData();
-        getGateKeeperService();
         getAuthSecretHal();
         mDeviceProvisionedObserver.onSystemReady();
 
@@ -1109,9 +1104,6 @@
     }
 
     private final void checkPasswordHavePermission() {
-        if (mContext.checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
-            EventLog.writeEvent(0x534e4554, "28251513", getCallingUid(), "");  // SafetyNet
-        }
         mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsHave");
     }
 
@@ -1676,6 +1668,7 @@
                                 + PERMISSION);
             }
         }
+        credential.validateBasicRequirements();
 
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -1774,10 +1767,6 @@
     }
 
     private void onPostPasswordChanged(LockscreenCredential newCredential, int userHandle) {
-        if (newCredential.isPattern()) {
-            setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle);
-        }
-
         updatePasswordHistory(newCredential, userHandle);
         mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userHandle);
     }
@@ -2239,17 +2228,6 @@
                 // credential has matched
                 mBiometricDeferredQueue.addPendingLockoutResetForUser(userId,
                         authResult.syntheticPassword.deriveGkPassword());
-
-                // perform verifyChallenge with synthetic password which generates the real GK auth
-                // token and response for the current user
-                response = mSpManager.verifyChallenge(getGateKeeperService(),
-                        authResult.syntheticPassword, 0L /* challenge */, userId);
-                if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                    // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
-                    // match the recorded GK password handle.
-                    Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                    return VerifyCredentialResponse.ERROR;
-                }
             }
         }
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -2645,7 +2623,7 @@
             return mGateKeeperService;
         }
 
-        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
+        final IBinder service = ServiceManager.waitForService(Context.GATEKEEPER_SERVICE);
         if (service != null) {
             try {
                 service.linkToDeath(new GateKeeperDiedRecipient(), 0);
@@ -2883,7 +2861,7 @@
      *
      * Also maintains the invariants described in {@link SyntheticPasswordManager} by
      * setting/clearing the protection (by the SP) on the user's auth-bound Keystore keys when the
-     * LSKF is added/removed, respectively.  If the new LSKF is nonempty, then the Gatekeeper auth
+     * LSKF is added/removed, respectively.  If an LSKF is being added, then the Gatekeeper auth
      * token is also refreshed.
      */
     @GuardedBy("mSpManager")
@@ -2900,9 +2878,7 @@
             // not needed by synchronizeUnifiedWorkChallengeForProfiles()
             profilePasswords = null;
 
-            if (mSpManager.hasSidForUser(userId)) {
-                mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
-            } else {
+            if (!mSpManager.hasSidForUser(userId)) {
                 mSpManager.newSidForUser(getGateKeeperService(), sp, userId);
                 mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
                 setKeystorePassword(sp.deriveKeyStorePassword(), userId);
@@ -3118,6 +3094,7 @@
     private boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle,
             byte[] token, int userId) {
         boolean result;
+        credential.validateBasicRequirements();
         synchronized (mSpManager) {
             if (!mSpManager.hasEscrowData(userId)) {
                 throw new SecurityException("Escrow token is disabled on the current user");
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index f107d0b..df95c69 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -16,8 +16,6 @@
 
 package com.android.server.locksettings;
 
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 
 import android.app.ActivityManager;
@@ -313,16 +311,8 @@
                 mLockPatternUtils.getRequestedPasswordMetrics(mCurrentUserId);
         final int requiredComplexity =
                 mLockPatternUtils.getRequestedPasswordComplexity(mCurrentUserId);
-        final List<PasswordValidationError> errors;
-        if (credential.isPassword() || credential.isPin()) {
-            errors = PasswordMetrics.validatePassword(requiredMetrics, requiredComplexity,
-                    credential.isPin(), credential.getCredential());
-        } else {
-            PasswordMetrics metrics = new PasswordMetrics(
-                    credential.isPattern() ? CREDENTIAL_TYPE_PATTERN : CREDENTIAL_TYPE_NONE);
-            errors = PasswordMetrics.validatePasswordMetrics(
-                    requiredMetrics, requiredComplexity, metrics);
-        }
+        final List<PasswordValidationError> errors =
+                PasswordMetrics.validateCredential(requiredMetrics, requiredComplexity, credential);
         if (!errors.isEmpty()) {
             getOutPrintWriter().println(
                     "New credential doesn't satisfy admin policies: " + errors.get(0));
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index e8fd6f8..3d3703a 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -31,6 +31,7 @@
 import android.hardware.weaver.WeaverConfig;
 import android.hardware.weaver.WeaverReadResponse;
 import android.hardware.weaver.WeaverReadStatus;
+import android.os.IBinder;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -71,7 +72,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-
 /**
  * A class that manages a user's synthetic password (SP) ({@link #SyntheticPassword}), along with a
  * set of SP protectors that are independent ways that the SP is protected.
@@ -500,7 +500,7 @@
 
     private final Context mContext;
     private LockSettingsStorage mStorage;
-    private IWeaver mWeaver;
+    private volatile IWeaver mWeaver;
     private WeaverConfig mWeaverConfig;
     private PasswordSlotManager mPasswordSlotManager;
 
@@ -531,17 +531,63 @@
         }
     }
 
-    private IWeaver getWeaverService() {
-        // Try to get the AIDL service first
+    private class WeaverDiedRecipient implements IBinder.DeathRecipient {
+        // Not synchronized on the outer class, since setting the pointer to null is atomic, and we
+        // don't want to have to worry about any sort of deadlock here.
+        @Override
+        public void binderDied() {
+            // Weaver died.  Try to recover by setting mWeaver to null, which makes
+            // getWeaverService() look up the service again.  This is done only as a simple
+            // robustness measure; it should not be relied on.  If this triggers, the root cause is
+            // almost certainly a bug in the device's Weaver implementation, which must be fixed.
+            Slog.wtf(TAG, "Weaver service has died");
+            mWeaver.asBinder().unlinkToDeath(this, 0);
+            mWeaver = null;
+        }
+    }
+
+    private @Nullable IWeaver getWeaverAidlService() {
+        final IWeaver aidlWeaver;
         try {
-            IWeaver aidlWeaver = IWeaver.Stub.asInterface(
-                    ServiceManager.waitForDeclaredService(IWeaver.DESCRIPTOR + "/default"));
-            if (aidlWeaver != null) {
-                Slog.i(TAG, "Using AIDL weaver service");
-                return aidlWeaver;
-            }
+            aidlWeaver =
+                    IWeaver.Stub.asInterface(
+                            ServiceManager.waitForDeclaredService(IWeaver.DESCRIPTOR + "/default"));
         } catch (SecurityException e) {
             Slog.w(TAG, "Does not have permissions to get AIDL weaver service");
+            return null;
+        }
+        if (aidlWeaver == null) {
+            return null;
+        }
+        final int aidlVersion;
+        try {
+            aidlVersion = aidlWeaver.getInterfaceVersion();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Cannot get AIDL weaver service version", e);
+            return null;
+        }
+        if (aidlVersion < 2) {
+            Slog.w(TAG,
+                    "Ignoring AIDL weaver service v"
+                            + aidlVersion
+                            + " because only v2 and later are supported");
+            return null;
+        }
+        Slog.i(TAG, "Found AIDL weaver service v" + aidlVersion);
+        return aidlWeaver;
+    }
+
+    private @Nullable IWeaver getWeaverServiceInternal() {
+        // Try to get the AIDL service first
+        IWeaver aidlWeaver = getWeaverAidlService();
+        if (aidlWeaver != null) {
+            Slog.i(TAG, "Using AIDL weaver service");
+            try {
+                aidlWeaver.asBinder().linkToDeath(new WeaverDiedRecipient(), 0);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Unable to register Weaver death recipient", e);
+            }
+            return aidlWeaver;
         }
 
         // If the AIDL service can't be found, look for the HIDL service
@@ -563,15 +609,20 @@
         return LockPatternUtils.isAutoPinConfirmFeatureAvailable();
     }
 
-    private synchronized boolean isWeaverAvailable() {
-        if (mWeaver != null) {
-            return true;
+    /**
+     * Returns a handle to the Weaver service, or null if Weaver is unavailable.  Note that not all
+     * devices support Weaver.
+     */
+    private synchronized @Nullable IWeaver getWeaverService() {
+        IWeaver weaver = mWeaver;
+        if (weaver != null) {
+            return weaver;
         }
 
         // Re-initialize weaver in case there was a transient error preventing access to it.
-        IWeaver weaver = getWeaverService();
+        weaver = getWeaverServiceInternal();
         if (weaver == null) {
-            return false;
+            return null;
         }
 
         final WeaverConfig weaverConfig;
@@ -579,19 +630,18 @@
             weaverConfig = weaver.getConfig();
         } catch (RemoteException | ServiceSpecificException e) {
             Slog.e(TAG, "Failed to get weaver config", e);
-            return false;
+            return null;
         }
         if (weaverConfig == null || weaverConfig.slots <= 0) {
             Slog.e(TAG, "Invalid weaver config");
-            return false;
+            return null;
         }
 
         mWeaver = weaver;
         mWeaverConfig = weaverConfig;
         mPasswordSlotManager.refreshActiveSlots(getUsedWeaverSlots());
         Slog.i(TAG, "Weaver service initialized");
-
-        return true;
+        return weaver;
     }
 
     /**
@@ -601,7 +651,7 @@
      *
      * @return the value stored in the weaver slot, or null if the operation fails
      */
-    private byte[] weaverEnroll(int slot, byte[] key, @Nullable byte[] value) {
+    private byte[] weaverEnroll(IWeaver weaver, int slot, byte[] key, @Nullable byte[] value) {
         if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
             throw new IllegalArgumentException("Invalid slot for weaver");
         }
@@ -614,7 +664,7 @@
             value = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize);
         }
         try {
-            mWeaver.write(slot, key, value);
+            weaver.write(slot, key, value);
         } catch (RemoteException e) {
             Slog.e(TAG, "weaver write binder call failed, slot: " + slot, e);
             return null;
@@ -643,7 +693,7 @@
      * the verification is successful, throttled or failed. If successful, the bound secret
      * is also returned.
      */
-    private VerifyCredentialResponse weaverVerify(int slot, byte[] key) {
+    private VerifyCredentialResponse weaverVerify(IWeaver weaver, int slot, byte[] key) {
         if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
             throw new IllegalArgumentException("Invalid slot for weaver");
         }
@@ -654,7 +704,7 @@
         }
         final WeaverReadResponse readResponse;
         try {
-            readResponse = mWeaver.read(slot, key);
+            readResponse = weaver.read(slot, key);
         } catch (RemoteException e) {
             Slog.e(TAG, "weaver read failed, slot: " + slot, e);
             return VerifyCredentialResponse.ERROR;
@@ -846,14 +896,15 @@
         int slot = loadWeaverSlot(protectorId, userId);
         destroyState(WEAVER_SLOT_NAME, protectorId, userId);
         if (slot != INVALID_WEAVER_SLOT) {
-            if (!isWeaverAvailable()) {
+            final IWeaver weaver = getWeaverService();
+            if (weaver == null) {
                 Slog.e(TAG, "Cannot erase Weaver slot because Weaver is unavailable");
                 return;
             }
             Set<Integer> usedSlots = getUsedWeaverSlots();
             if (!usedSlots.contains(slot)) {
                 Slogf.i(TAG, "Erasing Weaver slot %d", slot);
-                weaverEnroll(slot, null, null);
+                weaverEnroll(weaver, slot, null, null);
                 mPasswordSlotManager.markSlotDeleted(slot);
             } else {
                 Slogf.i(TAG, "Weaver slot %d was already reused; not erasing it", slot);
@@ -931,13 +982,14 @@
 
         Slogf.i(TAG, "Creating LSKF-based protector %016x for user %d", protectorId, userId);
 
-        if (isWeaverAvailable()) {
+        final IWeaver weaver = getWeaverService();
+        if (weaver != null) {
             // Weaver is available, so make the protector use it to verify the LSKF.  Do this even
             // if the LSKF is empty, as that gives us support for securely deleting the protector.
             int weaverSlot = getNextAvailableWeaverSlot();
             Slogf.i(TAG, "Enrolling LSKF for user %d into Weaver slot %d", userId, weaverSlot);
-            byte[] weaverSecret = weaverEnroll(weaverSlot, stretchedLskfToWeaverKey(stretchedLskf),
-                    null);
+            byte[] weaverSecret = weaverEnroll(weaver, weaverSlot,
+                    stretchedLskfToWeaverKey(stretchedLskf), null);
             if (weaverSecret == null) {
                 throw new IllegalStateException(
                         "Fail to enroll user password under weaver " + userId);
@@ -1024,7 +1076,8 @@
             }
             return VerifyCredentialResponse.fromGateKeeperResponse(response);
         } else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) {
-            if (!isWeaverAvailable()) {
+            final IWeaver weaver = getWeaverService();
+            if (weaver == null) {
                 Slog.e(TAG, "No weaver service to verify SP-based FRP credential");
                 return VerifyCredentialResponse.ERROR;
             }
@@ -1032,7 +1085,8 @@
             byte[] stretchedLskf = stretchLskf(userCredential, pwd);
             int weaverSlot = persistentData.userId;
 
-            return weaverVerify(weaverSlot, stretchedLskfToWeaverKey(stretchedLskf)).stripPayload();
+            return weaverVerify(weaver, weaverSlot,
+                    stretchedLskfToWeaverKey(stretchedLskf)).stripPayload();
         } else {
             Slog.e(TAG, "persistentData.type must be TYPE_SP_GATEKEEPER or TYPE_SP_WEAVER, but is "
                     + persistentData.type);
@@ -1134,7 +1188,7 @@
         TokenData tokenData = new TokenData();
         tokenData.mType = type;
         final byte[] secdiscardable = SecureRandomUtils.randomBytes(SECDISCARDABLE_LENGTH);
-        if (isWeaverAvailable()) {
+        if (getWeaverService() != null) {
             tokenData.weaverSecret = SecureRandomUtils.randomBytes(mWeaverConfig.valueSize);
             tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret,
                             PERSONALIZATION_WEAVER_TOKEN, secdiscardable);
@@ -1177,10 +1231,11 @@
             return false;
         }
         Slogf.i(TAG, "Creating token-based protector %016x for user %d", tokenHandle, userId);
-        if (isWeaverAvailable()) {
+        final IWeaver weaver = getWeaverService();
+        if (weaver != null) {
             int slot = getNextAvailableWeaverSlot();
             Slogf.i(TAG, "Using Weaver slot %d for new token-based protector", slot);
-            if (weaverEnroll(slot, null, tokenData.weaverSecret) == null) {
+            if (weaverEnroll(weaver, slot, null, tokenData.weaverSecret) == null) {
                 Slog.e(TAG, "Failed to enroll weaver secret when activating token");
                 return false;
             }
@@ -1269,12 +1324,14 @@
         int weaverSlot = loadWeaverSlot(protectorId, userId);
         if (weaverSlot != INVALID_WEAVER_SLOT) {
             // Protector uses Weaver to verify the LSKF
-            if (!isWeaverAvailable()) {
+            final IWeaver weaver = getWeaverService();
+            if (weaver == null) {
                 Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
                 result.gkResponse = VerifyCredentialResponse.ERROR;
                 return result;
             }
-            result.gkResponse = weaverVerify(weaverSlot, stretchedLskfToWeaverKey(stretchedLskf));
+            result.gkResponse = weaverVerify(weaver, weaverSlot,
+                    stretchedLskfToWeaverKey(stretchedLskf));
             if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
                 return result;
             }
@@ -1442,12 +1499,13 @@
         }
         int slotId = loadWeaverSlot(protectorId, userId);
         if (slotId != INVALID_WEAVER_SLOT) {
-            if (!isWeaverAvailable()) {
+            final IWeaver weaver = getWeaverService();
+            if (weaver == null) {
                 Slog.e(TAG, "Protector uses Weaver, but Weaver is unavailable");
                 result.gkResponse = VerifyCredentialResponse.ERROR;
                 return result;
             }
-            VerifyCredentialResponse response = weaverVerify(slotId, null);
+            VerifyCredentialResponse response = weaverVerify(weaver, slotId, null);
             if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
                     response.getGatekeeperHAT() == null) {
                 Slog.e(TAG,
@@ -1602,7 +1660,7 @@
     /** Destroy all weak token-based SP protectors for the given user. */
     public void destroyAllWeakTokenBasedProtectors(int userId) {
         List<Long> protectorIds =
-            mStorage.listSyntheticPasswordProtectorsForUser(SECDISCARDABLE_NAME, userId);
+            mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME, userId);
         for (long protectorId : protectorIds) {
             SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
                     protectorId, userId));
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 2f9536f..23532c1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -261,6 +261,8 @@
 
     private final OverlayActorEnforcer mActorEnforcer;
 
+    private int mPrevStartedUserId = -1;
+
     public OverlayManagerService(@NonNull final Context context) {
         super(context);
         try {
@@ -338,6 +340,10 @@
     }
 
     private void onStartUser(@UserIdInt int newUserId) {
+        // Do nothing when start a user that is the same as the one started previously.
+        if (newUserId == mPrevStartedUserId) {
+            return;
+        }
         try {
             traceBegin(TRACE_TAG_RRO, "OMS#onStartUser " + newUserId);
             // ensure overlays in the settings are up-to-date, and propagate
@@ -348,6 +354,7 @@
         } finally {
             traceEnd(TRACE_TAG_RRO);
         }
+        mPrevStartedUserId = newUserId;
     }
 
     private static String[] getDefaultOverlayPackages() {
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 39cd888..8bd2982 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -1050,7 +1050,7 @@
                 context.unregisterReceiver(this);
                 artManager.scheduleBackgroundDexoptJob();
             }
-        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+        }, new IntentFilter(Intent.ACTION_LOCKED_BOOT_COMPLETED));
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index 80d6ebb..85e11d6 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -34,8 +34,11 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Stream;
@@ -155,10 +158,27 @@
     private long getApksSize(File apkDir) {
         // TODO(b/249294752): also count apk sizes for failed installs
         final AtomicLong apksSize = new AtomicLong();
-        try (Stream<Path> walkStream = Files.walk(apkDir.toPath())) {
-            walkStream.filter(p -> p.toFile().isFile()
-                    && ApkLiteParseUtils.isApkFile(p.toFile())).forEach(
-                            f -> apksSize.addAndGet(f.toFile().length()));
+        try {
+            Files.walkFileTree(apkDir.toPath(), new SimpleFileVisitor<>() {
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                        throws IOException {
+                    if (dir.equals(apkDir.toPath())) {
+                        return FileVisitResult.CONTINUE;
+                    } else {
+                        return FileVisitResult.SKIP_SUBTREE;
+                    }
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                        throws IOException {
+                    if (file.toFile().isFile() && ApkLiteParseUtils.isApkFile(file.toFile())) {
+                        apksSize.addAndGet(file.toFile().length());
+                    }
+                    return FileVisitResult.CONTINUE;
+                }
+            });
         } catch (IOException e) {
             // ignore
         }
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index f0bf1ea8..d0c346a 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -334,7 +334,10 @@
                             ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_UNKNOWN),
                     cancellationReason,
                     durationMs,
-                    0);  // deprecated, used to be durationIncludingSleepMs
+                    0, // deprecated, used to be durationIncludingSleepMs
+                    0, // optimizedPackagesCount
+                    0, // packagesDependingOnBootClasspathCount
+                    0); // totalPackagesCount
         }
     }
 }
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 0ca5603..2007079 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -121,7 +121,7 @@
             impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
         } else if (getAvailableRollback(failedPackage) != null) {
             // Rollback is available, we may get a callback into #execute
-            impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_60;
+            impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
         } else if (anyRollbackAvailable) {
             // If any rollbacks are available, we will commit them
             impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_70;
diff --git a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
index c908acd..d5bc912 100644
--- a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
+++ b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java
@@ -24,9 +24,10 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.security.keymaster.IKeyAttestationApplicationIdProvider;
-import android.security.keymaster.KeyAttestationApplicationId;
-import android.security.keymaster.KeyAttestationPackageInfo;
+import android.security.keystore.IKeyAttestationApplicationIdProvider;
+import android.security.keystore.KeyAttestationApplicationId;
+import android.security.keystore.KeyAttestationPackageInfo;
+import android.security.keystore.Signature;
 
 /**
  * @hide
@@ -64,14 +65,25 @@
             for (int i = 0; i < packageNames.length; ++i) {
                 PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageNames[i],
                         PackageManager.GET_SIGNATURES, userId);
-                keyAttestationPackageInfos[i] = new KeyAttestationPackageInfo(packageNames[i],
-                        packageInfo.getLongVersionCode(), packageInfo.signatures);
+                KeyAttestationPackageInfo pInfo = new KeyAttestationPackageInfo();
+                pInfo.packageName = new String(packageNames[i]);
+                pInfo.versionCode = packageInfo.getLongVersionCode();
+                pInfo.signatures = new Signature[packageInfo.signatures.length];
+                for (int index = 0; index < packageInfo.signatures.length; index++) {
+                    Signature sign = new Signature();
+                    sign.data = packageInfo.signatures[index].toByteArray();
+                    pInfo.signatures[index] = sign;
+                }
+
+                keyAttestationPackageInfos[i] = pInfo;
             }
         } catch (NameNotFoundException nnfe) {
             throw new RemoteException(nnfe.getMessage());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        return new KeyAttestationApplicationId(keyAttestationPackageInfos);
+        KeyAttestationApplicationId attestAppId = new KeyAttestationApplicationId();
+        attestAppId.packageInfos = keyAttestationPackageInfos;
+        return attestAppId;
     }
 }
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 36529d82..635e11b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -31,7 +31,6 @@
 import android.app.trust.ITrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -42,11 +41,9 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -237,7 +234,6 @@
             mIdleTrustableTimeoutAlarmListenerForUser = new SparseArray<>();
     private AlarmManager mAlarmManager;
     private final Object mAlarmLock = new Object();
-    private final SettingsObserver mSettingsObserver;
 
     private final StrongAuthTracker mStrongAuthTracker;
 
@@ -279,7 +275,6 @@
         mLockPatternUtils = injector.getLockPatternUtils();
         mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mSettingsObserver = new SettingsObserver(mHandler);
     }
 
     @Override
@@ -307,103 +302,10 @@
         }
     }
 
-    // Extend unlock config and logic
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri TRUST_AGENTS_EXTEND_UNLOCK =
-                Settings.Secure.getUriFor(Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK);
-
-        private final Uri LOCK_SCREEN_WHEN_TRUST_LOST =
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST);
-
-        private final boolean mIsAutomotive;
-        private final ContentResolver mContentResolver;
-        private boolean mTrustAgentsNonrenewableTrust;
-        private boolean mLockWhenTrustLost;
-
-        /**
-         * Creates a settings observer
-         *
-         * @param handler The handler to run {@link #onChange} on, or null if none.
-         */
-        SettingsObserver(Handler handler) {
-            super(handler);
-
-            PackageManager packageManager = getContext().getPackageManager();
-            mIsAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-
-            mContentResolver = getContext().getContentResolver();
-            updateContentObserver();
-        }
-
-        void updateContentObserver() {
-            mContentResolver.unregisterContentObserver(this);
-            mContentResolver.registerContentObserver(TRUST_AGENTS_EXTEND_UNLOCK,
-                    false /* notifyForDescendents */,
-                    this /* observer */,
-                    mCurrentUser);
-            mContentResolver.registerContentObserver(LOCK_SCREEN_WHEN_TRUST_LOST,
-                    false /* notifyForDescendents */,
-                    this /* observer */,
-                    mCurrentUser);
-
-            // Update the value immediately
-            onChange(true /* selfChange */, TRUST_AGENTS_EXTEND_UNLOCK);
-            onChange(true /* selfChange */, LOCK_SCREEN_WHEN_TRUST_LOST);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (TRUST_AGENTS_EXTEND_UNLOCK.equals(uri)) {
-                // Smart lock should only grant non-renewable trust. The only exception is for
-                // automotive, where it can actively unlock the head unit.
-                int defaultValue = mIsAutomotive ? 0 : 1;
-
-                mTrustAgentsNonrenewableTrust =
-                        Settings.Secure.getIntForUser(
-                                mContentResolver,
-                                Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
-                                defaultValue,
-                                mCurrentUser) != 0;
-            } else if (LOCK_SCREEN_WHEN_TRUST_LOST.equals(uri)) {
-                mLockWhenTrustLost =
-                        Settings.Secure.getIntForUser(
-                                mContentResolver,
-                                Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
-                                0 /* default */,
-                                mCurrentUser) != 0;
-            }
-        }
-
-        boolean getTrustAgentsNonrenewableTrust() {
-            return mTrustAgentsNonrenewableTrust;
-        }
-
-        boolean getLockWhenTrustLost() {
-            return mLockWhenTrustLost;
-        }
-    }
-
-    private void maybeLockScreen(int userId) {
-        if (userId != mCurrentUser) {
-            return;
-        }
-
-        if (mSettingsObserver.getLockWhenTrustLost()) {
-            if (DEBUG) Slog.d(TAG, "Locking device because trust was lost");
-            try {
-                WindowManagerGlobal.getWindowManagerService().lockNow(null);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Error locking screen when trust was lost");
-            }
-
-            // If active unlocking is not allowed, cancel any pending trust timeouts because the
-            // screen is already locked.
-            TrustedTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
-            if (alarm != null && mSettingsObserver.getTrustAgentsNonrenewableTrust()) {
-                mAlarmManager.cancel(alarm);
-                alarm.setQueued(false /* isQueued */);
-            }
-        }
+    // Automotive head units can be unlocked by a trust agent, even when the agent doesn't use
+    // FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE.
+    private boolean isAutomotive() {
+        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
     }
 
     private void scheduleTrustTimeout(boolean override, boolean isTrustableTimeout) {
@@ -600,12 +502,10 @@
         synchronized (mUserTrustState) {
             wasTrusted = (mUserTrustState.get(userId) == TrustState.TRUSTED);
             wasTrustable = (mUserTrustState.get(userId) == TrustState.TRUSTABLE);
-            boolean isAutomotive = getContext().getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_AUTOMOTIVE);
             boolean renewingTrust = wasTrustable && (
                     (flags & TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0);
             boolean canMoveToTrusted =
-                    alreadyUnlocked || isFromUnlock || renewingTrust || isAutomotive;
+                    alreadyUnlocked || isFromUnlock || renewingTrust || isAutomotive();
             boolean upgradingTrustForCurrentUser = (userId == mCurrentUser);
 
             if (trustedByAtLeastOneAgent && wasTrusted) {
@@ -632,9 +532,7 @@
                 isNowTrusted, newlyUnlocked, userId, flags, getTrustGrantedMessages(userId));
         if (isNowTrusted != wasTrusted) {
             refreshDeviceLockedForUser(userId);
-            if (!isNowTrusted) {
-                maybeLockScreen(userId);
-            } else {
+            if (isNowTrusted) {
                 boolean isTrustableTimeout =
                         (flags & FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0;
                 // Every time we grant renewable trust we should override the idle trustable
@@ -1357,7 +1255,7 @@
         for (int i = 0; i < mActiveAgents.size(); i++) {
             AgentInfo info = mActiveAgents.valueAt(i);
             if (info.userId == userId) {
-                if (info.agent.isTrustableOrWaitingForDowngrade()) {
+                if (info.agent.isManagingTrust()) {
                     return true;
                 }
             }
@@ -1855,9 +1753,7 @@
             synchronized(mUsersUnlockedByBiometric) {
                 mUsersUnlockedByBiometric.put(userId, true);
             }
-            // In non-renewable trust mode we need to refresh trust state here, which will call
-            // refreshDeviceLockedForUser()
-            int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsNonrenewableTrust() ? 1 : 0;
+            int updateTrustOnUnlock = isAutomotive() ? 0 : 1;
             mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
                     updateTrustOnUnlock).sendToTarget();
             mHandler.obtainMessage(MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH, userId).sendToTarget();
@@ -1966,7 +1862,6 @@
                         break;
                     case MSG_SWITCH_USER:
                         mCurrentUser = msg.arg1;
-                        mSettingsObserver.updateContentObserver();
                         refreshDeviceLockedForUser(UserHandle.USER_ALL);
                         break;
                     case MSG_STOP_USER:
@@ -2196,7 +2091,6 @@
                 mLockPatternUtils.requireStrongAuth(
                         mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED, mUserId);
             }
-            maybeLockScreen(mUserId);
         }
 
         protected abstract void handleAlarm();
diff --git a/services/core/java/com/android/server/vibrator/OWNERS b/services/core/java/com/android/server/vibrator/OWNERS
index 08f0a90..da5a476 100644
--- a/services/core/java/com/android/server/vibrator/OWNERS
+++ b/services/core/java/com/android/server/vibrator/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 345036
+khalilahmad@google.com
 lsandrade@google.com
 michaelwr@google.com
-sbowden@google.com
\ No newline at end of file
+roosa@google.com
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 86f62a7..c1cc73b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5127,8 +5127,11 @@
             boolean deviceWideOnly) {
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)
-                && (isSystemUid(caller) || hasCallingOrSelfPermission(
-                permission.SET_INITIAL_LOCK)));
+                && (isSystemUid(caller)
+                    // Accept any permission that ILockSettings#setLockCredential() accepts.
+                    || hasCallingOrSelfPermission(permission.SET_INITIAL_LOCK)
+                    || hasCallingOrSelfPermission(permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS)
+                    || hasCallingOrSelfPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)));
         return getPasswordMinimumMetricsUnchecked(userHandle, deviceWideOnly);
     }
 
@@ -5725,20 +5728,17 @@
         final int callingUid = caller.getUid();
         final int userHandle = UserHandle.getUserId(callingUid);
         final boolean isPin = PasswordMetrics.isNumericOnly(password);
+        final LockscreenCredential newCredential;
+        if (isPin) {
+            newCredential = LockscreenCredential.createPin(password);
+        } else {
+            newCredential = LockscreenCredential.createPasswordOrNone(password);
+        }
         synchronized (getLockObject()) {
             final PasswordMetrics minMetrics = getPasswordMinimumMetricsUnchecked(userHandle);
-            final List<PasswordValidationError> validationErrors;
             final int complexity = getAggregatedPasswordComplexityLocked(userHandle);
-            // TODO: Consider changing validation API to take LockscreenCredential.
-            if (password.isEmpty()) {
-                validationErrors = PasswordMetrics.validatePasswordMetrics(
-                        minMetrics, complexity, new PasswordMetrics(CREDENTIAL_TYPE_NONE));
-            } else {
-                // TODO(b/120484642): remove getBytes() below
-                validationErrors = PasswordMetrics.validatePassword(
-                        minMetrics, complexity, isPin, password.getBytes());
-            }
-
+            final List<PasswordValidationError> validationErrors =
+                    PasswordMetrics.validateCredential(minMetrics, complexity, newCredential);
             if (!validationErrors.isEmpty()) {
                 Slogf.w(LOG_TAG, "Failed to reset password due to constraint violation: %s",
                         validationErrors.get(0));
@@ -5762,12 +5762,6 @@
         // Don't do this with the lock held, because it is going to call
         // back in to the service.
         final long ident = mInjector.binderClearCallingIdentity();
-        final LockscreenCredential newCredential;
-        if (isPin) {
-            newCredential = LockscreenCredential.createPin(password);
-        } else {
-            newCredential = LockscreenCredential.createPasswordOrNone(password);
-        }
         try {
             if (tokenHandle == 0 || token == null) {
                 if (!mLockPatternUtils.setLockCredential(newCredential,
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index 506e156..66ee696 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -58,7 +58,7 @@
         "mockito-robolectric-prebuilt",
         "platform-test-annotations",
         "testng",
-        "truth-prebuilt",
+        "truth",
     ],
 
     instrumentation_for: "BackupFrameworksServicesLib",
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 07ddda3..528fda2 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -43,7 +43,7 @@
         "services.core",
         "servicestests-core-utils",
         "servicestests-utils-mockito-extended",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: [
@@ -90,7 +90,7 @@
         "services.core",
         "servicestests-core-utils",
         "servicestests-utils-mockito-extended",
-        "truth-prebuilt",
+        "truth",
         "SimpleImeTestingLib",
         "SimpleImeImsLib",
     ],
diff --git a/services/tests/PackageManager/packageinstaller/Android.bp b/services/tests/PackageManager/packageinstaller/Android.bp
index 35d754b..e8fce8e 100644
--- a/services/tests/PackageManager/packageinstaller/Android.bp
+++ b/services/tests/PackageManager/packageinstaller/Android.bp
@@ -32,7 +32,7 @@
         "androidx.test.runner",
         "junit",
         "kotlin-test",
-        "truth-prebuilt",
+        "truth",
     ],
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp
index 19fdf60..81fd90d 100644
--- a/services/tests/PackageManagerComponentOverrideTests/Android.bp
+++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp
@@ -29,7 +29,7 @@
 android_test {
     name: "PackageManagerComponentOverrideTests",
     srcs: [
-        "src/**/*.kt"
+        "src/**/*.kt",
     ],
     static_libs: [
         "androidx.test.runner",
@@ -37,7 +37,7 @@
         "services.core",
         "servicestests-utils-mockito-extended",
         "testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
-        "truth-prebuilt",
+        "truth",
     ],
 
     jni_libs: [
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
index 9c4e6fd..ad7af44 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
+++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
@@ -29,7 +29,7 @@
     static_libs: [
         "compatibility-device-util-axt",
         "androidx.test.runner",
-        "truth-prebuilt",
+        "truth",
         "Harrier",
     ],
     platform_apis: true,
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index c7a71ee..42a8f9b 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -30,7 +30,7 @@
     libs: [
         "tradefed",
         "junit",
-        "truth-prebuilt",
+        "truth",
     ],
     static_libs: [
         "ApexInstallHelper",
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
index 462c580..cea9c59 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
@@ -38,6 +38,6 @@
         "junit-params",
         "androidx.test.ext.junit",
         "androidx.test.rules",
-        "truth-prebuilt",
+        "truth",
     ],
 }
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
index 5718474..ed5f2b5 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
@@ -28,6 +28,6 @@
         "androidx.test.runner",
         "junit",
         "kotlin-test",
-        "truth-prebuilt",
+        "truth",
     ],
 }
diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp
index 3176f06..47d2422 100644
--- a/services/tests/PackageManagerServiceTests/server/Android.bp
+++ b/services/tests/PackageManagerServiceTests/server/Android.bp
@@ -41,7 +41,7 @@
         "mockito-target-minus-junit4",
         "platform-test-annotations",
         "ShortcutManagerTestUtils",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "ub-uiautomator",
         "platformprotosnano",
@@ -52,7 +52,7 @@
         "servicestests-utils",
         "service-permission.impl",
         "testng",
-        "truth-prebuilt",
+        "truth",
         "junit",
         "junit-params",
         "platform-compat-test-rules",
diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp
index 9b3b8c35..85059838 100644
--- a/services/tests/PackageManagerServiceTests/unit/Android.bp
+++ b/services/tests/PackageManagerServiceTests/unit/Android.bp
@@ -37,7 +37,7 @@
         "services.core",
         "servicestests-utils",
         "servicestests-core-utils",
-        "truth-prebuilt",
+        "truth",
     ],
     jni_libs: [
         "libdexmakerjvmtiagent",
diff --git a/services/tests/RemoteProvisioningServiceTests/Android.bp b/services/tests/RemoteProvisioningServiceTests/Android.bp
index fc2c085..19c9136 100644
--- a/services/tests/RemoteProvisioningServiceTests/Android.bp
+++ b/services/tests/RemoteProvisioningServiceTests/Android.bp
@@ -30,8 +30,8 @@
         "mockito-target",
         "service-rkp.impl",
         "services.core",
-        "truth-prebuilt",
-        "truth-java8-extension-jar",
+        "truth",
+        "truth-java8-extension",
     ],
     test_suites: [
         "device-tests",
diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp
index e724e804..9dacfea 100644
--- a/services/tests/apexsystemservices/Android.bp
+++ b/services/tests/apexsystemservices/Android.bp
@@ -34,7 +34,7 @@
         "compatibility-host-util",
         "cts-install-lib-host",
         "frameworks-base-hostutils",
-        "truth-prebuilt",
+        "truth",
         "modules-utils-build-testing",
     ],
     test_suites: [
diff --git a/services/tests/inprocesstests/Android.bp b/services/tests/inprocesstests/Android.bp
index 7c237ac..086e84b 100644
--- a/services/tests/inprocesstests/Android.bp
+++ b/services/tests/inprocesstests/Android.bp
@@ -14,7 +14,7 @@
         "androidx.test.core",
         "androidx.test.rules",
         "services.core",
-        "truth-prebuilt",
+        "truth",
         "platform-test-annotations",
     ],
     test_suites: ["general-tests"],
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 101498a..f56f290 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -67,7 +67,7 @@
         "servicestests-core-utils",
         "servicestests-utils-mockito-extended",
         "testables",
-        "truth-prebuilt",
+        "truth",
         // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
         "testng",
         "compatibility-device-util-axt",
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
index 35d4ffd..a140730 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
@@ -145,7 +145,7 @@
                 observer.onHealthCheckFailed(null,
                         PackageWatchdog.FAILURE_REASON_NATIVE_CRASH, 1));
         // non-native crash for the package
-        assertEquals(PackageWatchdog.PackageHealthObserverImpact.USER_IMPACT_LEVEL_60,
+        assertEquals(PackageWatchdog.PackageHealthObserverImpact.USER_IMPACT_LEVEL_30,
                 observer.onHealthCheckFailed(testFailedPackage,
                         PackageWatchdog.FAILURE_REASON_APP_CRASH, 1));
         // non-native crash for a different package
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 16e1b45..f770f8c 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -48,7 +48,7 @@
         "mockito-target-minus-junit4",
         "platform-test-annotations",
         "ShortcutManagerTestUtils",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "ub-uiautomator",
         "platformprotosnano",
@@ -59,7 +59,7 @@
         // TODO: remove once Android migrates to JUnit 4.12,
         // which provides assertThrows
         "testng",
-        "truth-prebuilt",
+        "truth",
         "junit",
         "junit-params",
         "ActivityContext",
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 99a3b80..cc07cce 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -46,7 +46,6 @@
 import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_OPEN;
 import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_PERSONAL;
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
-import static android.app.admin.PasswordMetrics.computeForPasswordOrPin;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
 import static android.location.LocationManager.FUSED_PROVIDER;
 import static android.location.LocationManager.GPS_PROVIDER;
@@ -5479,8 +5478,7 @@
 
         reset(mContext.spiedContext);
 
-        PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin(
-                "abcdXYZ5".getBytes(), /* isPin */ false);
+        PasswordMetrics passwordMetricsNoSymbols = metricsForPassword("abcdXYZ5");
 
         setActivePasswordState(passwordMetricsNoSymbols);
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
@@ -5507,8 +5505,7 @@
         reset(mContext.spiedContext);
         assertThat(dpm.isActivePasswordSufficient()).isFalse();
 
-        PasswordMetrics passwordMetricsWithSymbols = computeForPasswordOrPin(
-                "abcd.XY5".getBytes(), /* isPin */ false);
+        PasswordMetrics passwordMetricsWithSymbols = metricsForPassword("abcd.XY5");
 
         setActivePasswordState(passwordMetricsWithSymbols);
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
@@ -5564,7 +5561,7 @@
         parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM);
 
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("184342".getBytes(), /* isPin */ true));
+                .thenReturn(metricsForPin("184342"));
 
         // Numeric password is compliant with current requirement (QUALITY_NUMERIC set explicitly
         // on the parent admin)
@@ -5685,7 +5682,7 @@
 
         // Set a work challenge and verify profile.isActivePasswordSufficient is now true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId))
-                .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("abcdXYZ5"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5710,7 +5707,7 @@
 
         // Set a work challenge and verify profile.isActivePasswordSufficient is now true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId))
-                .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true));
+                .thenReturn(metricsForPin("5156"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5735,7 +5732,7 @@
 
         // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("acbdXYZ5"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5758,7 +5755,7 @@
 
         // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true));
+                .thenReturn(metricsForPin("1234"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5783,7 +5780,7 @@
 
         // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("abcdXYZ5"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5806,7 +5803,7 @@
 
         // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true));
+                .thenReturn(metricsForPin("51567548"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5831,7 +5828,7 @@
 
         // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("abcdXYZ5"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -5854,7 +5851,7 @@
 
         // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true
         when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM))
-                .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true));
+                .thenReturn(metricsForPin("5156"));
         assertThat(dpm.isActivePasswordSufficient()).isTrue();
         assertThat(parentDpm.isActivePasswordSufficient()).isTrue();
     }
@@ -6909,7 +6906,7 @@
                 .thenReturn(CALLER_USER_HANDLE);
         when(getServices().lockSettingsInternal
                 .getUserPasswordMetrics(CALLER_USER_HANDLE))
-                .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("asdf"));
 
         assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
     }
@@ -6929,10 +6926,10 @@
 
         when(getServices().lockSettingsInternal
                 .getUserPasswordMetrics(CALLER_USER_HANDLE))
-                .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("asdf"));
         when(getServices().lockSettingsInternal
                 .getUserPasswordMetrics(parentUser.id))
-                .thenReturn(computeForPasswordOrPin("parentUser".getBytes(), /* isPin */ false));
+                .thenReturn(metricsForPassword("parentUser"));
 
         assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
     }
@@ -7654,15 +7651,13 @@
         assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE);
 
         reset(mContext.spiedContext);
-        PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin(
-                "1234".getBytes(), /* isPin */ true);
+        PasswordMetrics passwordMetricsNoSymbols = metricsForPin("1234");
         setActivePasswordState(passwordMetricsNoSymbols);
         assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_LOW);
         assertThat(dpm.isActivePasswordSufficient()).isFalse();
 
         reset(mContext.spiedContext);
-        passwordMetricsNoSymbols = computeForPasswordOrPin(
-                "84125312943a".getBytes(), /* isPin */ false);
+        passwordMetricsNoSymbols = metricsForPassword("84125312943a");
         setActivePasswordState(passwordMetricsNoSymbols);
         assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
         // using isActivePasswordSufficient
@@ -8838,4 +8833,12 @@
         assumeTrue("device doesn't support deprecated password APIs",
                 isDeprecatedPasswordApisSupported());
     }
+
+    private static PasswordMetrics metricsForPassword(String password) {
+        return PasswordMetrics.computeForCredential(LockscreenCredential.createPassword(password));
+    }
+
+    private static PasswordMetrics metricsForPin(String pin) {
+        return PasswordMetrics.computeForCredential(LockscreenCredential.createPin(pin));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index d8e4fda..7189383 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -285,6 +285,7 @@
         assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier());
     }
 
+    @FlakyTest(bugId = 297949293)
     @Test
     public void getDeviceStateInfo_baseStateAndCommittedStateNotSet() throws RemoteException {
         // Create a provider and a service without an initial base state.
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 60a033f..5a62d92 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -77,6 +77,26 @@
         testSetCredentialFailsWithoutLockScreen(PRIMARY_USER_ID, newPassword("password"));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetTooShortPatternFails() throws RemoteException {
+        mService.setLockCredential(newPattern("123"), nonePassword(), PRIMARY_USER_ID);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetTooShortPinFails() throws RemoteException {
+        mService.setLockCredential(newPin("123"), nonePassword(), PRIMARY_USER_ID);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetTooShortPassword() throws RemoteException {
+        mService.setLockCredential(newPassword("123"), nonePassword(), PRIMARY_USER_ID);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetPasswordWithInvalidChars() throws RemoteException {
+        mService.setLockCredential(newPassword("§µ¿¶¥£"), nonePassword(), PRIMARY_USER_ID);
+    }
+
     @Test
     public void testSetPatternPrimaryUser() throws RemoteException {
         setAndVerifyCredential(PRIMARY_USER_ID, newPattern("123456789"));
@@ -94,7 +114,7 @@
 
     @Test
     public void testChangePatternPrimaryUser() throws RemoteException {
-        testChangeCredential(PRIMARY_USER_ID, newPassword("!£$%^&*(())"), newPattern("1596321"));
+        testChangeCredential(PRIMARY_USER_ID, newPassword("password"), newPattern("1596321"));
     }
 
     @Test
@@ -185,7 +205,7 @@
         assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
 
-        setCredential(PRIMARY_USER_ID, newPassword("pwd"), primaryPassword);
+        setCredential(PRIMARY_USER_ID, newPassword("password"), primaryPassword);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                 profilePassword, MANAGED_PROFILE_USER_ID, 0 /* flags */)
                 .getResponseCode());
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index ce0347d..37a6d22 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -215,12 +215,12 @@
     @Test
     public void testChangeCredentialKeepsAuthSecret() throws RemoteException {
         LockscreenCredential password = newPassword("password");
-        LockscreenCredential badPassword = newPassword("new");
+        LockscreenCredential newPassword = newPassword("newPassword");
 
         initSpAndSetCredential(PRIMARY_USER_ID, password);
-        mService.setLockCredential(badPassword, password, PRIMARY_USER_ID);
+        mService.setLockCredential(newPassword, password, PRIMARY_USER_ID);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                badPassword, PRIMARY_USER_ID, 0 /* flags */).getResponseCode());
+                newPassword, PRIMARY_USER_ID, 0 /* flags */).getResponseCode());
 
         // Check the same secret was passed each time
         ArgumentCaptor<byte[]> secret = ArgumentCaptor.forClass(byte[].class);
@@ -781,7 +781,7 @@
                 password, PRIMARY_USER_ID, 0 /* flags */).getResponseCode());
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
-        mService.onCleanupUser(PRIMARY_USER_ID);
+        mService.onUserStopped(PRIMARY_USER_ID);
         assertNull(mLocalService.getUserPasswordMetrics(PRIMARY_USER_ID));
 
         assertTrue(mLocalService.unlockUserWithToken(handle, token, PRIMARY_USER_ID));
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeakEscrowTokenTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeakEscrowTokenTests.java
index 2c9ba34..e8b7ad7 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/WeakEscrowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeakEscrowTokenTests.java
@@ -169,7 +169,7 @@
         assertTrue(mService.isWeakEscrowTokenActive(handle, PRIMARY_USER_ID));
         assertTrue(mService.isWeakEscrowTokenValid(handle, token, PRIMARY_USER_ID));
 
-        mService.onCleanupUser(PRIMARY_USER_ID);
+        mService.onUserStopped(PRIMARY_USER_ID);
         assertNull(mLocalService.getUserPasswordMetrics(PRIMARY_USER_ID));
 
         assertTrue(mLocalService.unlockUserWithToken(handle, token, PRIMARY_USER_ID));
diff --git a/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java b/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java
new file mode 100644
index 0000000..949f8e7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.net;
+
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.text.TextUtils;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.R;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnProfile;
+import com.android.server.connectivity.Vpn;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class LockdownVpnTrackerTest {
+    private static final NetworkCapabilities TEST_CELL_NC = new NetworkCapabilities.Builder()
+            .addTransportType(TRANSPORT_CELLULAR)
+            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
+            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+            .build();
+    private static final LinkProperties TEST_CELL_LP = new LinkProperties();
+
+    static {
+        TEST_CELL_LP.setInterfaceName("rmnet0");
+        TEST_CELL_LP.addLinkAddress(new LinkAddress("192.0.2.2/25"));
+    }
+
+    // Use a context wrapper instead of a mock since LockdownVpnTracker builds notifications which
+    // is tedious and currently unnecessary to mock.
+    private final Context mContext = new ContextWrapper(InstrumentationRegistry.getContext()) {
+        @Override
+        public Object getSystemService(String name) {
+            if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
+            if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager;
+
+            return super.getSystemService(name);
+        }
+    };
+    @Mock private ConnectivityManager mCm;
+    @Mock private Vpn mVpn;
+    @Mock private NotificationManager mNotificationManager;
+    @Mock private NetworkInfo mVpnNetworkInfo;
+    @Mock private VpnConfig mVpnConfig;
+    @Mock private Network mNetwork;
+    @Mock private Network mNetwork2;
+    @Mock private Network mVpnNetwork;
+
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private VpnProfile mProfile;
+
+    private VpnProfile createTestVpnProfile() {
+        final String profileName = "testVpnProfile";
+        final VpnProfile profile = new VpnProfile(profileName);
+        profile.name = "My VPN";
+        profile.server = "192.0.2.1";
+        profile.dnsServers = "8.8.8.8";
+        profile.ipsecIdentifier = "My ipsecIdentifier";
+        profile.ipsecSecret = "My PSK";
+        profile.type = VpnProfile.TYPE_IKEV2_IPSEC_PSK;
+
+        return profile;
+    }
+
+    private NetworkCallback getDefaultNetworkCallback() {
+        final ArgumentCaptor<NetworkCallback> callbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        verify(mCm).registerSystemDefaultNetworkCallback(callbackCaptor.capture(), eq(mHandler));
+        return callbackCaptor.getValue();
+    }
+
+    private NetworkCallback getVpnNetworkCallback() {
+        final ArgumentCaptor<NetworkCallback> callbackCaptor =
+                ArgumentCaptor.forClass(NetworkCallback.class);
+        verify(mCm).registerNetworkCallback(any(), callbackCaptor.capture(), eq(mHandler));
+        return callbackCaptor.getValue();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mHandlerThread = new HandlerThread("LockdownVpnTrackerTest");
+        mHandlerThread.start();
+        mHandler = mHandlerThread.getThreadHandler();
+
+        doReturn(mVpnNetworkInfo).when(mVpn).getNetworkInfo();
+        doReturn(false).when(mVpnNetworkInfo).isConnectedOrConnecting();
+        doReturn(mVpnConfig).when(mVpn).getLegacyVpnConfig();
+        // mVpnConfig is a mock but the production code will try to add addresses in this array
+        // assuming it's non-null, so it needs to be initialized.
+        mVpnConfig.addresses = new ArrayList<>();
+
+        mProfile = createTestVpnProfile();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+            mHandlerThread.join();
+        }
+    }
+
+    private LockdownVpnTracker initAndVerifyLockdownVpnTracker() {
+        final LockdownVpnTracker lockdownVpnTracker =
+                new LockdownVpnTracker(mContext, mHandler, mVpn, mProfile);
+        lockdownVpnTracker.init();
+        verify(mVpn).setEnableTeardown(false);
+        verify(mVpn).setLockdown(true);
+        verify(mCm).setLegacyLockdownVpnEnabled(true);
+        verify(mVpn).stopVpnRunnerPrivileged();
+        verify(mNotificationManager).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS));
+
+        return lockdownVpnTracker;
+    }
+
+    private void callCallbacksForNetworkConnect(NetworkCallback callback, Network network,
+            NetworkCapabilities nc, LinkProperties lp, boolean blocked) {
+        callback.onAvailable(network);
+        callback.onCapabilitiesChanged(network, nc);
+        callback.onLinkPropertiesChanged(network, lp);
+        callback.onBlockedStatusChanged(network, blocked);
+    }
+
+    private void callCallbacksForNetworkConnect(NetworkCallback callback, Network network) {
+        callCallbacksForNetworkConnect(
+                callback, network, TEST_CELL_NC, TEST_CELL_LP, true /* blocked */);
+    }
+
+    private boolean isExpectedNotification(Notification notification, int titleRes, int iconRes) {
+        if (!NOTIFICATION_CHANNEL_VPN.equals(notification.getChannelId())) {
+            return false;
+        }
+        final CharSequence expectedTitle = mContext.getString(titleRes);
+        final CharSequence actualTitle = notification.extras.getCharSequence(
+                Notification.EXTRA_TITLE);
+        if (!TextUtils.equals(expectedTitle, actualTitle)) {
+            return false;
+        }
+        return notification.getSmallIcon().getResId() == iconRes;
+    }
+
+    @Test
+    public void testShutdown() {
+        final LockdownVpnTracker lockdownVpnTracker = initAndVerifyLockdownVpnTracker();
+        final NetworkCallback defaultCallback = getDefaultNetworkCallback();
+        final NetworkCallback vpnCallback = getVpnNetworkCallback();
+        clearInvocations(mVpn, mCm, mNotificationManager);
+
+        lockdownVpnTracker.shutdown();
+        verify(mVpn).stopVpnRunnerPrivileged();
+        verify(mVpn).setLockdown(false);
+        verify(mCm).setLegacyLockdownVpnEnabled(false);
+        verify(mNotificationManager).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS));
+        verify(mVpn).setEnableTeardown(true);
+        verify(mCm).unregisterNetworkCallback(defaultCallback);
+        verify(mCm).unregisterNetworkCallback(vpnCallback);
+    }
+
+    @Test
+    public void testDefaultNetworkConnected() {
+        initAndVerifyLockdownVpnTracker();
+        final NetworkCallback defaultCallback = getDefaultNetworkCallback();
+        clearInvocations(mVpn, mCm, mNotificationManager);
+
+        // mNetwork connected and available.
+        callCallbacksForNetworkConnect(defaultCallback, mNetwork);
+
+        // Vpn is starting
+        verify(mVpn).startLegacyVpnPrivileged(mProfile, mNetwork, TEST_CELL_LP);
+        verify(mNotificationManager).notify(any(), eq(SystemMessage.NOTE_VPN_STATUS),
+                argThat(notification -> isExpectedNotification(notification,
+                        R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected)));
+    }
+
+    private void doTestDefaultLpChanged(LinkProperties startingLp, LinkProperties newLp) {
+        initAndVerifyLockdownVpnTracker();
+        final NetworkCallback defaultCallback = getDefaultNetworkCallback();
+        callCallbacksForNetworkConnect(
+                defaultCallback, mNetwork, TEST_CELL_NC, startingLp, true /* blocked */);
+        clearInvocations(mVpn, mCm, mNotificationManager);
+
+        // LockdownVpnTracker#handleStateChangedLocked() is not called on the same network even if
+        // the LinkProperties change.
+        defaultCallback.onLinkPropertiesChanged(mNetwork, newLp);
+
+        // Ideally the VPN should start if it hasn't already, but it doesn't because nothing calls
+        // LockdownVpnTracker#handleStateChangedLocked. This is a bug.
+        // TODO: consider fixing this.
+        verify(mVpn, never()).stopVpnRunnerPrivileged();
+        verify(mVpn, never()).startLegacyVpnPrivileged(any(), any(), any());
+        verify(mNotificationManager, never()).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS));
+    }
+
+    @Test
+    public void testDefaultLPChanged_V4AddLinkAddressV4() {
+        final LinkProperties lp = new LinkProperties(TEST_CELL_LP);
+        lp.setInterfaceName("rmnet0");
+        lp.addLinkAddress(new LinkAddress("192.0.2.3/25"));
+        doTestDefaultLpChanged(TEST_CELL_LP, lp);
+    }
+
+    @Test
+    public void testDefaultLPChanged_V4AddLinkAddressV6() {
+        final LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName("rmnet0");
+        lp.addLinkAddress(new LinkAddress("192.0.2.3/25"));
+        final LinkProperties newLp = new LinkProperties(lp);
+        newLp.addLinkAddress(new LinkAddress("2001:db8::1/64"));
+        doTestDefaultLpChanged(lp, newLp);
+    }
+
+    @Test
+    public void testDefaultLPChanged_V6AddLinkAddressV4() {
+        final LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName("rmnet0");
+        lp.addLinkAddress(new LinkAddress("2001:db8::1/64"));
+        final LinkProperties newLp = new LinkProperties(lp);
+        newLp.addLinkAddress(new LinkAddress("192.0.2.3/25"));
+        doTestDefaultLpChanged(lp, newLp);
+    }
+
+    @Test
+    public void testDefaultLPChanged_AddLinkAddressV4() {
+        final LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName("rmnet0");
+        doTestDefaultLpChanged(lp, TEST_CELL_LP);
+    }
+
+    @Test
+    public void testDefaultNetworkChanged() {
+        initAndVerifyLockdownVpnTracker();
+        final NetworkCallback defaultCallback = getDefaultNetworkCallback();
+        final NetworkCallback vpnCallback = getVpnNetworkCallback();
+        callCallbacksForNetworkConnect(defaultCallback, mNetwork);
+        clearInvocations(mVpn, mCm, mNotificationManager);
+
+        // New network and LinkProperties received
+        final NetworkCapabilities wifiNc = new NetworkCapabilities.Builder()
+                .addTransportType(TRANSPORT_WIFI)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+                .build();
+        final LinkProperties wifiLp = new LinkProperties();
+        wifiLp.setInterfaceName("wlan0");
+        callCallbacksForNetworkConnect(
+                defaultCallback, mNetwork2, wifiNc, wifiLp, true /* blocked */);
+
+        // Vpn is restarted.
+        verify(mVpn).stopVpnRunnerPrivileged();
+        verify(mVpn).startLegacyVpnPrivileged(mProfile, mNetwork2, wifiLp);
+        verify(mNotificationManager, never()).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS));
+        verify(mNotificationManager).notify(any(), eq(SystemMessage.NOTE_VPN_STATUS),
+                argThat(notification -> isExpectedNotification(notification,
+                        R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected)));
+
+        // Vpn is Connected
+        doReturn(true).when(mVpnNetworkInfo).isConnectedOrConnecting();
+        doReturn(true).when(mVpnNetworkInfo).isConnected();
+        vpnCallback.onAvailable(mVpnNetwork);
+        verify(mNotificationManager).notify(any(), eq(SystemMessage.NOTE_VPN_STATUS),
+                argThat(notification -> isExpectedNotification(notification,
+                        R.string.vpn_lockdown_connected, R.drawable.vpn_connected)));
+
+    }
+
+    @Test
+    public void testSystemDefaultLost() {
+        initAndVerifyLockdownVpnTracker();
+        final NetworkCallback defaultCallback = getDefaultNetworkCallback();
+        // mNetwork connected
+        callCallbacksForNetworkConnect(defaultCallback, mNetwork);
+        clearInvocations(mVpn, mCm, mNotificationManager);
+
+        defaultCallback.onLost(mNetwork);
+
+        // Vpn is stopped
+        verify(mVpn).stopVpnRunnerPrivileged();
+        verify(mNotificationManager).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS));
+    }
+}
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 94f2d2e..b1eeba5 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -36,7 +36,7 @@
         "hamcrest-library",
         "servicestests-utils",
         "testables",
-        "truth-prebuilt",
+        "truth",
         // TODO: remove once Android migrates to JUnit 4.12,
         // which provides assertThrows
         "testng",
diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp
index e704ebf..744cb63 100644
--- a/services/tests/voiceinteractiontests/Android.bp
+++ b/services/tests/voiceinteractiontests/Android.bp
@@ -43,7 +43,7 @@
         "services.soundtrigger",
         "servicestests-core-utils",
         "servicestests-utils-mockito-extended",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: [
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
index 6a1674b..63b8e17 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
@@ -38,13 +38,16 @@
 import android.os.Process;
 import android.os.RemoteException;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.internal.util.FakeLatencyTracker;
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.Timeout;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 import org.mockito.ArgumentCaptor;
@@ -52,8 +55,12 @@
 import org.mockito.MockitoAnnotations;
 
 @RunWith(JUnit4.class)
+@FlakyTest(bugId = 275746222)
 public class SoundTriggerMiddlewareLoggingLatencyTest {
 
+    @Rule
+    public Timeout mGlobalTimeout = Timeout.seconds(30);
+
     private FakeLatencyTracker mLatencyTracker;
     @Mock
     private BatteryStatsInternal mBatteryStatsInternal;
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index e5371975..0997d15 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -55,7 +55,7 @@
         "platform-test-annotations",
         "servicestests-utils",
         "testng",
-        "truth-prebuilt",
+        "truth",
         "testables",
         "ub-uiautomator",
         "hamcrest-library",
diff --git a/test-mock/api/current.txt b/test-mock/api/current.txt
index d1a68d4..241e691 100644
--- a/test-mock/api/current.txt
+++ b/test-mock/api/current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.test.mock {
 
   @Deprecated public class MockAccountManager {
diff --git a/test-mock/api/removed.txt b/test-mock/api/removed.txt
index 1496c35..fa2fbd2 100644
--- a/test-mock/api/removed.txt
+++ b/test-mock/api/removed.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.test.mock {
 
   public class MockContext extends android.content.Context {
diff --git a/test-mock/api/system-current.txt b/test-mock/api/system-current.txt
index 9e022f0..2b5132e 100644
--- a/test-mock/api/system-current.txt
+++ b/test-mock/api/system-current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.test.mock {
 
   public class MockContext extends android.content.Context {
diff --git a/test-mock/api/system-removed.txt b/test-mock/api/system-removed.txt
index d802177..14191eb 100644
--- a/test-mock/api/system-removed.txt
+++ b/test-mock/api/system-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 35f076f..1752edc 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -1,4 +1,6 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
 package android.test.mock {
 
   public class MockContext extends android.content.Context {
diff --git a/test-mock/api/test-removed.txt b/test-mock/api/test-removed.txt
index d802177..14191eb 100644
--- a/test-mock/api/test-removed.txt
+++ b/test-mock/api/test-removed.txt
@@ -1 +1,3 @@
 // Signature format: 2.0
+// - add-additional-overrides=no
+// - migrating=Migration in progress see b/299366704
diff --git a/tests/BatteryStatsPerfTest/Android.bp b/tests/BatteryStatsPerfTest/Android.bp
index 5233a5b..c2a7015 100644
--- a/tests/BatteryStatsPerfTest/Android.bp
+++ b/tests/BatteryStatsPerfTest/Android.bp
@@ -27,7 +27,7 @@
     static_libs: [
         "androidx.test.rules",
         "apct-perftests-utils",
-        "truth-prebuilt",
+        "truth",
     ],
     platform_apis: true,
     certificate: "platform",
diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp
index dc6bdff..0dbc022 100644
--- a/tests/BinaryTransparencyHostTest/Android.bp
+++ b/tests/BinaryTransparencyHostTest/Android.bp
@@ -30,7 +30,7 @@
         "compatibility-host-util",
     ],
     static_libs: [
-        "truth-prebuilt",
+        "truth",
     ],
     data: [
         ":BinaryTransparencyTestApp",
diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp
index c4faf7f..1fb73e2 100644
--- a/tests/BlobStoreTestUtils/Android.bp
+++ b/tests/BlobStoreTestUtils/Android.bp
@@ -22,12 +22,12 @@
 }
 
 java_library {
-  name: "BlobStoreTestUtils",
-  srcs: ["src/**/*.java"],
-  static_libs: [
-    "truth-prebuilt",
-    "androidx.test.uiautomator_uiautomator",
-    "androidx.test.ext.junit",
-  ],
-  sdk_version: "test_current",
+    name: "BlobStoreTestUtils",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "truth",
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.ext.junit",
+    ],
+    sdk_version: "test_current",
 }
diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp
index ca30267..5d49120 100644
--- a/tests/ChoreographerTests/Android.bp
+++ b/tests/ChoreographerTests/Android.bp
@@ -34,7 +34,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "com.google.android.material_material",
-        "truth-prebuilt",
+        "truth",
     ],
     jni_libs: [
         "libchoreographertests_jni",
diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.bp b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
index 448d46f..3f2c808 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/Android.bp
+++ b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
@@ -47,7 +47,7 @@
 
     static_libs: [
         "androidx.test.rules",
-        "truth-prebuilt",
+        "truth",
     ],
 
     compile_multilib: "both",
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 4ba538e..ba5b795 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -44,7 +44,7 @@
         "flickerlib",
         "flickerlib-apphelpers",
         "flickerlib-helpers",
-        "truth-prebuilt",
+        "truth",
         "launcher-helper-lib",
         "launcher-aosp-tapl",
         "platform-test-annotations",
@@ -71,7 +71,7 @@
     static_libs: [
         "flickerlib",
         "flickerlib-helpers",
-        "truth-prebuilt",
+        "truth",
         "app-helpers-core",
     ],
 }
@@ -90,7 +90,7 @@
         "flickerlib",
         "flickerlib-apphelpers",
         "flickerlib-helpers",
-        "truth-prebuilt",
+        "truth",
         "app-helpers-core",
         "wm-flicker-window-extensions",
     ],
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 4fa6fbe..292fbcb 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -24,7 +24,7 @@
         "mockito-target-minus-junit4",
         "services.core.unboosted",
         "testables",
-        "truth-prebuilt",
+        "truth",
         "androidx.test.uiautomator_uiautomator",
     ],
     test_suites: ["device-tests"],
diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp
index 84845c6..58ceb3f 100644
--- a/tests/InputMethodStressTest/Android.bp
+++ b/tests/InputMethodStressTest/Android.bp
@@ -26,7 +26,7 @@
         "compatibility-device-util-axt",
         "platform-test-annotations",
         "platform-test-rules",
-        "truth-prebuilt",
+        "truth",
     ],
     test_suites: [
         "general-tests",
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
index ef45864..ddec8fa 100644
--- a/tests/Internal/Android.bp
+++ b/tests/Internal/Android.bp
@@ -19,7 +19,7 @@
         "junit",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
         "platform-test-annotations",
     ],
     java_resource_dirs: ["res"],
diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp
index 4e0b0a8..909ca59 100644
--- a/tests/LocalizationTest/Android.bp
+++ b/tests/LocalizationTest/Android.bp
@@ -34,7 +34,7 @@
         "androidx.test.ext.junit",
         "androidx.test.rules",
         "mockito-target-extended-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
     jni_libs: [
         // For mockito extended
diff --git a/tests/MidiTests/Android.bp b/tests/MidiTests/Android.bp
index 254770d..fcacab3 100644
--- a/tests/MidiTests/Android.bp
+++ b/tests/MidiTests/Android.bp
@@ -31,7 +31,7 @@
         "mockito-target-inline-minus-junit4",
         "platform-test-annotations",
         "services.midi",
-        "truth-prebuilt",
+        "truth",
     ],
     jni_libs: ["libdexmakerjvmtiagent"],
     certificate: "platform",
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 1e1dc84..e0e6c4c 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -32,7 +32,7 @@
         "androidx.test.rules",
         "services.core",
         "services.net",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: ["android.test.runner"],
     jni_libs: [
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index f0f9c4b..fd992cf 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -38,7 +38,7 @@
         "androidx.test.ext.junit",
         "mockito-target-minus-junit4",
         "testng",
-        "truth-prebuilt",
+        "truth",
         "platform-compat-test-rules",
     ],
 }
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
index 5f91f9d0..f6a41c2 100644
--- a/tests/PlatformCompatGating/test-rules/Android.bp
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -29,7 +29,7 @@
     static_libs: [
         "junit",
         "androidx.test.core",
-        "truth-prebuilt",
-        "core-compat-test-rules"
+        "truth",
+        "core-compat-test-rules",
     ],
 }
diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp
index dc75f00..d34f780 100644
--- a/tests/SurfaceViewBufferTests/Android.bp
+++ b/tests/SurfaceViewBufferTests/Android.bp
@@ -23,7 +23,10 @@
 
 android_test {
     name: "SurfaceViewBufferTests",
-    srcs: ["**/*.java","**/*.kt"],
+    srcs: [
+        "**/*.java",
+        "**/*.kt",
+    ],
     manifest: "AndroidManifest.xml",
     test_config: "AndroidTest.xml",
     platform_apis: true,
@@ -41,7 +44,7 @@
         "kotlin-stdlib",
         "kotlinx-coroutines-android",
         "flickerlib",
-        "truth-prebuilt",
+        "truth",
         "cts-wm-util",
         "CtsSurfaceValidatorLib",
     ],
@@ -60,7 +63,7 @@
         "libandroid",
     ],
     include_dirs: [
-        "system/core/include"
+        "system/core/include",
     ],
     stl: "libc++_static",
     cflags: [
diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp
index 9b72d35..2a92c42 100644
--- a/tests/TaskOrganizerTest/Android.bp
+++ b/tests/TaskOrganizerTest/Android.bp
@@ -25,7 +25,10 @@
 
 android_test {
     name: "TaskOrganizerTest",
-    srcs: ["**/*.java","**/*.kt"],
+    srcs: [
+        "**/*.java",
+        "**/*.kt",
+    ],
     manifest: "AndroidManifest.xml",
     test_config: "AndroidTest.xml",
     platform_apis: true,
@@ -39,6 +42,6 @@
         "kotlin-stdlib",
         "kotlinx-coroutines-android",
         "flickerlib",
-        "truth-prebuilt",
+        "truth",
     ],
-}
\ No newline at end of file
+}
diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp
index 81ec265..b968e5d 100644
--- a/tests/TelephonyCommonTests/Android.bp
+++ b/tests/TelephonyCommonTests/Android.bp
@@ -32,11 +32,11 @@
     static_libs: [
         "mockito-target-extended",
         "androidx.test.rules",
-        "truth-prebuilt",
+        "truth",
         "platform-test-annotations",
         "androidx.core_core",
         "androidx.fragment_fragment",
-        "androidx.test.ext.junit"
+        "androidx.test.ext.junit",
     ],
 
     jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index c216bce..4e75a1d 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -28,7 +28,7 @@
         "flag-junit",
         "mockito-target-minus-junit4",
         "servicestests-utils",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "android.test.runner",
diff --git a/tests/TrustTests/src/android/trust/test/CanUnlockWithActiveUnlockTest.kt b/tests/TrustTests/src/android/trust/test/IsActiveUnlockRunningTest.kt
similarity index 100%
rename from tests/TrustTests/src/android/trust/test/CanUnlockWithActiveUnlockTest.kt
rename to tests/TrustTests/src/android/trust/test/IsActiveUnlockRunningTest.kt
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 9bfcc18..ddb3649 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -30,7 +30,7 @@
         "androidx.test.uiautomator_uiautomator",
         "compatibility-device-util-axt",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
     ],
     test_suites: [
         "general-tests",
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index 97fbf5b..c02d8e9 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -31,7 +31,7 @@
         "androidx.test.rules",
         "mockito-target-inline-minus-junit4",
         "platform-test-annotations",
-        "truth-prebuilt",
+        "truth",
         "UsbManagerTestLib",
     ],
     jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/UsbManagerTests/lib/Android.bp b/tests/UsbManagerTests/lib/Android.bp
index 994484c..4e5a70fe 100644
--- a/tests/UsbManagerTests/lib/Android.bp
+++ b/tests/UsbManagerTests/lib/Android.bp
@@ -34,7 +34,7 @@
         "services.core",
         "services.net",
         "services.usb",
-        "truth-prebuilt",
+        "truth",
         "androidx.core_core",
     ],
     libs: [
diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp
index 9328b67..1c2f746 100644
--- a/tests/UsbTests/Android.bp
+++ b/tests/UsbTests/Android.bp
@@ -34,7 +34,7 @@
         "services.core",
         "services.net",
         "services.usb",
-        "truth-prebuilt",
+        "truth",
         "UsbManagerTestLib",
     ],
     jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp
index 7af76e1..bbd46c5 100644
--- a/tests/componentalias/Android.bp
+++ b/tests/componentalias/Android.bp
@@ -25,7 +25,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "mockito-target-extended-minus-junit4",
-        "truth-prebuilt",
+        "truth",
         "ub-uiautomator",
     ],
     libs: ["android.test.base"],
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index 87da09a..8c644cf 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -49,16 +49,19 @@
     kDeprecated = 0x01,
     kSystemApi = 0x02,
     kTestApi = 0x04,
+    kFlaggedApi = 0x08,
   };
 
   StringPiece doc_str;
   uint32_t bit_mask;
   StringPiece annotation;
+  bool preserve_params;
 };
 
-static std::array<AnnotationRule, 2> sAnnotationRules = {{
-    {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi"},
-    {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi"},
+static std::array<AnnotationRule, 3> sAnnotationRules = {{
+    {"@SystemApi", AnnotationRule::kSystemApi, "@android.annotation.SystemApi", true},
+    {"@TestApi", AnnotationRule::kTestApi, "@android.annotation.TestApi", false},
+    {"@FlaggedApi", AnnotationRule::kFlaggedApi, "@android.annotation.FlaggedApi", true},
 }};
 
 void AnnotationProcessor::AppendCommentLine(std::string comment) {
@@ -73,12 +76,11 @@
     std::string::size_type idx = comment.find(rule.doc_str.data());
     if (idx != std::string::npos) {
       // Captures all parameters associated with the specified annotation rule
-      // by matching the first pair of parantheses after the rule.
-      std::regex re(std::string(rule.doc_str) += "\\s*\\((.+)\\)");
+      // by matching the first pair of parentheses after the rule.
+      std::regex re(std::string(rule.doc_str).append(R"(\s*\((.+)\))"));
       std::smatch match_result;
       const bool is_match = std::regex_search(comment, match_result, re);
-      // We currently only capture and preserve parameters for SystemApi.
-      if (is_match && rule.bit_mask == AnnotationRule::kSystemApi) {
+      if (is_match && rule.preserve_params) {
         annotation_parameter_map_[rule.bit_mask] = match_result[1].str();
         comment.erase(comment.begin() + match_result.position(),
                       comment.begin() + match_result.position() + match_result.length());
diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp
index 6bc8902..e98e96b 100644
--- a/tools/aapt2/java/AnnotationProcessor_test.cpp
+++ b/tools/aapt2/java/AnnotationProcessor_test.cpp
@@ -76,6 +76,36 @@
   EXPECT_THAT(annotations, HasSubstr("This is a system API"));
 }
 
+TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationAndRemovesFromComment) {
+  AnnotationProcessor processor;
+  processor.AppendComment("@FlaggedApi This is a flagged API");
+
+  std::string annotations;
+  StringOutputStream out(&annotations);
+  Printer printer(&out);
+  processor.Print(&printer);
+  out.Flush();
+
+  EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi"));
+  EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
+  EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
+}
+
+TEST(AnnotationProcessorTest, EmitsFlaggedApiAnnotationParamsAndRemovesFromComment) {
+  AnnotationProcessor processor;
+  processor.AppendComment("@FlaggedApi (\"android.flags.my_flag\") This is a flagged API");
+
+  std::string annotations;
+  StringOutputStream out(&annotations);
+  Printer printer(&out);
+  processor.Print(&printer);
+  out.Flush();
+
+  EXPECT_THAT(annotations, HasSubstr("@android.annotation.FlaggedApi(\"android.flags.my_flag\")"));
+  EXPECT_THAT(annotations, Not(HasSubstr("@FlaggedApi")));
+  EXPECT_THAT(annotations, HasSubstr("This is a flagged API"));
+}
+
 TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) {
   AnnotationProcessor processor;
   processor.AppendComment("@TestApi This is a test API");
diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp
index a7d69039..ecc283b 100644
--- a/tools/processors/immutability/Android.bp
+++ b/tools/processors/immutability/Android.bp
@@ -50,7 +50,7 @@
 
     static_libs: [
         "compile-testing-prebuilt",
-        "truth-prebuilt",
+        "truth",
         "junit",
         "kotlin-reflect",
         "ImmutabilityAnnotationProcessorHostLibrary",
diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp
index 7059c52..9c755b7 100644
--- a/tools/processors/intdef_mappings/Android.bp
+++ b/tools/processors/intdef_mappings/Android.bp
@@ -38,7 +38,7 @@
 
     static_libs: [
         "compile-testing-prebuilt",
-        "truth-prebuilt",
+        "truth",
         "junit",
         "guava",
         "libintdef-annotation-processor",
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 7a29969..5a0f742 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -40,7 +40,7 @@
         "frameworks-base-testutils",
         "guava",
         "mockito-target-minus-junit4",
-        "truth-prebuilt",
+        "truth",
     ],
 
     libs: [