Merge "Clarify details in docs for binderDied()" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 5f30216..54baae5 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -141,6 +141,7 @@
 aconfig_declarations {
     name: "com.android.window.flags.window-aconfig",
     package: "com.android.window.flags",
+    container: "system",
     srcs: ["core/java/android/window/flags/*.aconfig"],
 }
 
@@ -154,6 +155,7 @@
 aconfig_declarations {
     name: "com.android.hardware.input.input-aconfig",
     package: "com.android.hardware.input",
+    container: "system",
     srcs: ["core/java/android/hardware/input/*.aconfig"],
 }
 
@@ -173,6 +175,7 @@
 aconfig_declarations {
     name: "com.android.text.flags-aconfig",
     package: "com.android.text.flags",
+    container: "system",
     srcs: ["core/java/android/text/flags/*.aconfig"],
 }
 
@@ -191,6 +194,7 @@
 aconfig_declarations {
     name: "android.location.flags-aconfig",
     package: "android.location.flags",
+    container: "system",
     srcs: [
         "location/java/android/location/flags/*.aconfig",
     ],
@@ -206,6 +210,7 @@
 aconfig_declarations {
     name: "android.nfc.flags-aconfig",
     package: "android.nfc",
+    container: "system",
     srcs: ["nfc/java/android/nfc/*.aconfig"],
 }
 
@@ -236,6 +241,7 @@
 aconfig_declarations {
     name: "android.security.flags-aconfig",
     package: "android.security",
+    container: "system",
     srcs: ["core/java/android/security/*.aconfig"],
 }
 
@@ -256,6 +262,7 @@
 aconfig_declarations {
     name: "android.app.usage.flags-aconfig",
     package: "android.app.usage",
+    container: "system",
     srcs: ["core/java/android/app/usage/*.aconfig"],
 }
 
@@ -269,6 +276,7 @@
 aconfig_declarations {
     name: "android.os.flags-aconfig",
     package: "android.os",
+    container: "system",
     srcs: ["core/java/android/os/*.aconfig"],
 }
 
@@ -300,6 +308,7 @@
 aconfig_declarations {
     name: "android.companion.virtualdevice.flags-aconfig",
     package: "android.companion.virtualdevice.flags",
+    container: "system",
     srcs: ["core/java/android/companion/virtual/flags/*.aconfig"],
 }
 
@@ -312,6 +321,7 @@
 aconfig_declarations {
     name: "android.companion.virtual.flags-aconfig",
     package: "android.companion.virtual.flags",
+    container: "system",
     srcs: ["core/java/android/companion/virtual/*.aconfig"],
 }
 
@@ -319,6 +329,7 @@
 aconfig_declarations {
     name: "android.view.inputmethod.flags-aconfig",
     package: "android.view.inputmethod",
+    container: "system",
     srcs: ["core/java/android/view/inputmethod/flags.aconfig"],
 }
 
@@ -332,6 +343,7 @@
 aconfig_declarations {
     name: "android.os.vibrator.flags-aconfig",
     package: "android.os.vibrator",
+    container: "system",
     srcs: ["core/java/android/os/vibrator/*.aconfig"],
 }
 
@@ -345,6 +357,7 @@
 aconfig_declarations {
     name: "android.view.flags-aconfig",
     package: "android.view.flags",
+    container: "system",
     srcs: ["core/java/android/view/flags/*.aconfig"],
 }
 
@@ -363,6 +376,7 @@
 aconfig_declarations {
     name: "android.view.accessibility.flags-aconfig",
     package: "android.view.accessibility",
+    container: "system",
     srcs: ["core/java/android/view/accessibility/flags/*.aconfig"],
 }
 
@@ -381,6 +395,7 @@
 aconfig_declarations {
     name: "android.hardware.flags-aconfig",
     package: "android.hardware.flags",
+    container: "system",
     srcs: ["core/java/android/hardware/flags/*.aconfig"],
 }
 
@@ -394,6 +409,7 @@
 aconfig_declarations {
     name: "android.widget.flags-aconfig",
     package: "android.widget.flags",
+    container: "system",
     srcs: ["core/java/android/widget/flags/*.aconfig"],
 }
 
@@ -413,6 +429,7 @@
 aconfig_declarations {
     name: "android.content.pm.flags-aconfig",
     package: "android.content.pm",
+    container: "system",
     srcs: ["core/java/android/content/pm/flags.aconfig"],
 }
 
@@ -433,6 +450,7 @@
 aconfig_declarations {
     name: "android.content.res.flags-aconfig",
     package: "android.content.res",
+    container: "system",
     srcs: ["core/java/android/content/res/*.aconfig"],
 }
 
@@ -446,6 +464,7 @@
 aconfig_declarations {
     name: "com.android.media.flags.bettertogether-aconfig",
     package: "com.android.media.flags",
+    container: "system",
     srcs: [
         "media/java/android/media/flags/media_better_together.aconfig",
         "media/java/android/media/flags/fade_manager_configuration.aconfig",
@@ -462,6 +481,7 @@
 aconfig_declarations {
     name: "android.media.tv.flags-aconfig",
     package: "android.media.tv.flags",
+    container: "system",
     srcs: ["media/java/android/media/tv/flags/media_tv.aconfig"],
 }
 
@@ -475,6 +495,7 @@
 aconfig_declarations {
     name: "android.permission.flags-aconfig",
     package: "android.permission.flags",
+    container: "system",
     srcs: ["core/java/android/permission/flags.aconfig"],
 }
 
@@ -494,6 +515,7 @@
 aconfig_declarations {
     name: "android.database.sqlite-aconfig",
     package: "android.database.sqlite",
+    container: "system",
     srcs: ["core/java/android/database/sqlite/*.aconfig"],
 }
 
@@ -507,6 +529,7 @@
 aconfig_declarations {
     name: "android.hardware.biometrics.flags-aconfig",
     package: "android.hardware.biometrics",
+    container: "system",
     srcs: ["core/java/android/hardware/biometrics/flags.aconfig"],
 }
 
@@ -546,6 +569,7 @@
 aconfig_declarations {
     name: "android.multiuser.flags-aconfig",
     package: "android.multiuser",
+    container: "system",
     srcs: ["core/java/android/content/pm/multiuser.aconfig"],
 }
 
@@ -559,6 +583,7 @@
 aconfig_declarations {
     name: "android.app.flags-aconfig",
     package: "android.app",
+    container: "system",
     srcs: ["core/java/android/app/*.aconfig"],
 }
 
@@ -572,6 +597,7 @@
 aconfig_declarations {
     name: "android.hardware.radio.flags-aconfig",
     package: "android.hardware.radio",
+    container: "system",
     srcs: ["core/java/android/hardware/radio/*.aconfig"],
 }
 
@@ -585,6 +611,7 @@
 aconfig_declarations {
     name: "android.credentials.flags-aconfig",
     package: "android.credentials.flags",
+    container: "system",
     srcs: ["core/java/android/credentials/flags.aconfig"],
 }
 
@@ -598,6 +625,7 @@
 aconfig_declarations {
     name: "android.view.contentprotection.flags-aconfig",
     package: "android.view.contentprotection.flags",
+    container: "system",
     srcs: ["core/java/android/view/contentprotection/flags/*.aconfig"],
 }
 
@@ -611,6 +639,7 @@
 aconfig_declarations {
     name: "com.android.server.flags.pinner-aconfig",
     package: "com.android.server.flags",
+    container: "system",
     srcs: ["services/core/java/com/android/server/flags/pinner.aconfig"],
 }
 
@@ -624,6 +653,7 @@
 aconfig_declarations {
     name: "android.service.controls.flags-aconfig",
     package: "android.service.controls.flags",
+    container: "system",
     srcs: ["core/java/android/service/controls/flags/*.aconfig"],
 }
 
@@ -637,6 +667,7 @@
 aconfig_declarations {
     name: "android.service.voice.flags-aconfig",
     package: "android.service.voice.flags",
+    container: "system",
     srcs: ["core/java/android/service/voice/flags/*.aconfig"],
 }
 
@@ -650,6 +681,7 @@
 aconfig_declarations {
     name: "android.service.autofill.flags-aconfig",
     package: "android.service.autofill",
+    container: "system",
     srcs: [
         "services/autofill/bugfixes.aconfig",
         "services/autofill/features.aconfig",
@@ -666,6 +698,7 @@
 aconfig_declarations {
     name: "android.companion.flags-aconfig",
     package: "android.companion",
+    container: "system",
     srcs: ["core/java/android/companion/*.aconfig"],
 }
 
@@ -679,6 +712,7 @@
 aconfig_declarations {
     name: "android.net.platform.flags-aconfig",
     package: "android.net.platform.flags",
+    container: "system",
     srcs: ["core/java/android/net/flags.aconfig"],
     visibility: [":__subpackages__"],
 }
@@ -687,6 +721,7 @@
 aconfig_declarations {
     name: "com.android.net.thread.platform.flags-aconfig",
     package: "com.android.net.thread.platform.flags",
+    container: "system",
     srcs: ["core/java/android/net/thread/flags.aconfig"],
 }
 
@@ -707,6 +742,7 @@
 aconfig_declarations {
     name: "android.media.playback.flags-aconfig",
     package: "com.android.media.playback.flags",
+    container: "system",
     srcs: ["media/jni/playback_flags.aconfig"],
 }
 
@@ -725,6 +761,7 @@
 aconfig_declarations {
     name: "android.net.vcn.flags-aconfig",
     package: "android.net.vcn",
+    container: "system",
     srcs: ["core/java/android/net/vcn/*.aconfig"],
 }
 
@@ -738,6 +775,7 @@
 aconfig_declarations {
     name: "device_policy_aconfig_flags",
     package: "android.app.admin.flags",
+    container: "system",
     srcs: [
         "core/java/android/app/admin/flags/flags.aconfig",
     ],
@@ -758,6 +796,7 @@
 aconfig_declarations {
     name: "android.service.chooser.flags-aconfig",
     package: "android.service.chooser",
+    container: "system",
     srcs: ["core/java/android/service/chooser/flags.aconfig"],
 }
 
@@ -771,6 +810,7 @@
 aconfig_declarations {
     name: "framework-jobscheduler-job.flags-aconfig",
     package: "android.app.job",
+    container: "system",
     srcs: ["apex/jobscheduler/framework/aconfig/job.aconfig"],
 }
 
@@ -784,6 +824,7 @@
 aconfig_declarations {
     name: "android.service.dreams.flags-aconfig",
     package: "android.service.dreams",
+    container: "system",
     srcs: ["core/java/android/service/dreams/flags.aconfig"],
 }
 
@@ -797,6 +838,7 @@
 aconfig_declarations {
     name: "android.service.notification.flags-aconfig",
     package: "android.service.notification",
+    container: "system",
     srcs: ["core/java/android/service/notification/flags.aconfig"],
 }
 
@@ -810,6 +852,7 @@
 aconfig_declarations {
     name: "android.app.smartspace.flags-aconfig",
     package: "android.app.smartspace.flags",
+    container: "system",
     srcs: ["core/java/android/app/smartspace/flags.aconfig"],
 }
 
@@ -830,6 +873,7 @@
 aconfig_declarations {
     name: "android.view.contentcapture.flags-aconfig",
     package: "android.view.contentcapture.flags",
+    container: "system",
     srcs: ["core/java/android/view/contentcapture/flags/*.aconfig"],
 }
 
@@ -843,6 +887,7 @@
 aconfig_declarations {
     name: "android.hardware.usb.flags-aconfig",
     package: "android.hardware.usb.flags",
+    container: "system",
     srcs: ["core/java/android/hardware/usb/flags/*.aconfig"],
 }
 
@@ -863,6 +908,7 @@
 aconfig_declarations {
     name: "android.tracing.flags-aconfig",
     package: "android.tracing",
+    container: "system",
     srcs: ["core/java/android/tracing/flags.aconfig"],
 }
 
@@ -876,6 +922,7 @@
 aconfig_declarations {
     name: "android.appwidget.flags-aconfig",
     package: "android.appwidget.flags",
+    container: "system",
     srcs: ["core/java/android/appwidget/flags.aconfig"],
 }
 
@@ -889,6 +936,7 @@
 aconfig_declarations {
     name: "android.server.app.flags-aconfig",
     package: "android.server.app",
+    container: "system",
     srcs: ["services/core/java/com/android/server/app/flags.aconfig"],
 }
 
@@ -902,6 +950,7 @@
 aconfig_declarations {
     name: "android.webkit.flags-aconfig",
     package: "android.webkit",
+    container: "system",
     srcs: [
         "core/java/android/webkit/*.aconfig",
         "services/core/java/com/android/server/webkit/*.aconfig",
@@ -918,6 +967,7 @@
 aconfig_declarations {
     name: "android.provider.flags-aconfig",
     package: "android.provider",
+    container: "system",
     srcs: ["core/java/android/provider/*.aconfig"],
 }
 
@@ -931,6 +981,7 @@
 aconfig_declarations {
     name: "android.crashrecovery.flags-aconfig",
     package: "android.crashrecovery.flags",
+    container: "system",
     srcs: ["packages/CrashRecovery/aconfig/flags.aconfig"],
 }
 
diff --git a/DREAM_MANAGER_OWNERS b/DREAM_MANAGER_OWNERS
new file mode 100644
index 0000000..48bde60
--- /dev/null
+++ b/DREAM_MANAGER_OWNERS
@@ -0,0 +1 @@
+brycelee@google.com
diff --git a/apex/jobscheduler/framework/aconfig/job.aconfig b/apex/jobscheduler/framework/aconfig/job.aconfig
index e73b434..6dbb969 100644
--- a/apex/jobscheduler/framework/aconfig/job.aconfig
+++ b/apex/jobscheduler/framework/aconfig/job.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.job"
+container: "system"
 
 flag {
     name: "enforce_minimum_time_windows"
diff --git a/apex/jobscheduler/service/aconfig/Android.bp b/apex/jobscheduler/service/aconfig/Android.bp
index 3ba7aa2..7f1fd47 100644
--- a/apex/jobscheduler/service/aconfig/Android.bp
+++ b/apex/jobscheduler/service/aconfig/Android.bp
@@ -2,6 +2,7 @@
 aconfig_declarations {
     name: "service-deviceidle.flags-aconfig",
     package: "com.android.server.deviceidle",
+    container: "system",
     srcs: [
         "device_idle.aconfig",
     ],
@@ -17,6 +18,7 @@
 aconfig_declarations {
     name: "service-job.flags-aconfig",
     package: "com.android.server.job",
+    container: "system",
     srcs: [
         "job.aconfig",
     ],
diff --git a/apex/jobscheduler/service/aconfig/device_idle.aconfig b/apex/jobscheduler/service/aconfig/device_idle.aconfig
index fc24b30..7a5e4bf 100644
--- a/apex/jobscheduler/service/aconfig/device_idle.aconfig
+++ b/apex/jobscheduler/service/aconfig/device_idle.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.deviceidle"
+container: "system"
 
 flag {
     name: "disable_wakelocks_in_light_idle"
diff --git a/apex/jobscheduler/service/aconfig/job.aconfig b/apex/jobscheduler/service/aconfig/job.aconfig
index c65e506..db8124e 100644
--- a/apex/jobscheduler/service/aconfig/job.aconfig
+++ b/apex/jobscheduler/service/aconfig/job.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.job"
+container: "system"
 
 flag {
     name: "relax_prefetch_connectivity_constraint_only_on_charger"
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 6383ed8..a49ad98 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -618,6 +618,7 @@
      * List of end times for app-IDs that are temporarily marked as being allowed to access
      * the network and acquire wakelocks. Times are in milliseconds.
      */
+    @GuardedBy("this")
     private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
             = new SparseArray<>();
 
@@ -4999,7 +5000,9 @@
                 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
                     return -1;
                 }
-                dumpTempWhitelistSchedule(pw, false);
+                synchronized (this) {
+                    dumpTempWhitelistScheduleLocked(pw, false);
+                }
             }
         } else if ("except-idle-whitelist".equals(cmd)) {
             getContext().enforceCallingOrSelfPermission(
@@ -5283,7 +5286,7 @@
                     pw.println();
                 }
             }
-            dumpTempWhitelistSchedule(pw, true);
+            dumpTempWhitelistScheduleLocked(pw, true);
 
             size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
             if (size > 0) {
@@ -5411,7 +5414,8 @@
         }
     }
 
-    void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
+    @GuardedBy("this")
+    void dumpTempWhitelistScheduleLocked(PrintWriter pw, boolean printTitle) {
         final int size = mTempWhitelistAppIdEndTimes.size();
         if (size > 0) {
             String prefix = "";
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index 3e277e8..f77f1c6 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -44,13 +44,13 @@
             removed_api_file: ":non-updatable-removed.txt",
         },
         last_released: {
-            api_file: ":android-non-updatable.api.public.latest",
-            removed_api_file: ":android-non-updatable-removed.api.public.latest",
+            api_file: ":android-non-updatable.api.combined.public.latest",
+            removed_api_file: ":android-non-updatable-removed.api.combined.public.latest",
             baseline_file: ":android-non-updatable-incompatibilities.api.public.latest",
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.public.latest",
+            new_since: ":android.api.combined.public.latest",
             baseline_file: ":non-updatable-lint-baseline.txt",
         },
     },
@@ -124,13 +124,13 @@
             removed_api_file: ":non-updatable-system-removed.txt",
         },
         last_released: {
-            api_file: ":android-non-updatable.api.system.latest",
-            removed_api_file: ":android-non-updatable-removed.api.system.latest",
+            api_file: ":android-non-updatable.api.combined.system.latest",
+            removed_api_file: ":android-non-updatable-removed.api.combined.system.latest",
             baseline_file: ":android-non-updatable-incompatibilities.api.system.latest",
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.system.latest",
+            new_since: ":android.api.combined.system.latest",
             baseline_file: ":non-updatable-system-lint-baseline.txt",
         },
     },
@@ -185,7 +185,7 @@
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.test.latest",
+            new_since: ":android.api.combined.test.latest",
             baseline_file: ":non-updatable-test-lint-baseline.txt",
         },
     },
@@ -263,13 +263,13 @@
             removed_api_file: ":non-updatable-module-lib-removed.txt",
         },
         last_released: {
-            api_file: ":android-non-updatable.api.module-lib.latest",
-            removed_api_file: ":android-non-updatable-removed.api.module-lib.latest",
+            api_file: ":android-non-updatable.api.combined.module-lib.latest",
+            removed_api_file: ":android-non-updatable-removed.api.combined.module-lib.latest",
             baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest",
         },
         api_lint: {
             enabled: true,
-            new_since: ":android.api.module-lib.latest",
+            new_since: ":android.api.combined.module-lib.latest",
             baseline_file: ":non-updatable-module-lib-lint-baseline.txt",
         },
     },
@@ -1135,31 +1135,47 @@
     ],
 }
 
-droidstubs {
-    name: "api_versions_public",
-    srcs: [":android_stubs_current_with_test_libs{.jar}"],
+// Defaults for `droidstubs` modules that generate `api-versions.xml` files for
+// the various API surfaces.
+stubs_defaults {
+    name: "api_versions_base_defaults",
+    defaults_visibility: ["//visibility:private"],
     generate_stubs: false,
     api_levels_annotations_enabled: true,
     api_levels_annotations_dirs: [
         "sdk-dir",
         "api-versions-jars-dir",
     ],
-    api_levels_sdk_type: "public",
+}
+
+// Defaults for `droidstubs` modules that generate complete `api-versions.xml`
+// files, i.e. include SDK extensions.
+stubs_defaults {
+    name: "api_versions_complete_defaults",
+    defaults_visibility: ["//visibility:private"],
+    defaults: ["api_versions_base_defaults"],
     extensions_info_file: ":sdk-extensions-info",
+}
+
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about all the public APIs, both updatable and non-updatable and historic
+// information about all previous dessert and SDK extension releases.
+droidstubs {
+    name: "api_versions_public",
+    defaults: ["api_versions_complete_defaults"],
+    srcs: [":android_stubs_current_with_test_libs{.jar}"],
+    api_levels_sdk_type: "public",
     visibility: ["//frameworks/base"],
 }
 
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about all the system APIs, both updatable and non-updatable and historic
+// information about all previous dessert and SDK extension releases.
 droidstubs {
     name: "api_versions_system",
+    defaults: ["api_versions_complete_defaults"],
     srcs: [":android_system_stubs_current_with_test_libs{.jar}"],
-    generate_stubs: false,
-    api_levels_annotations_enabled: true,
-    api_levels_annotations_dirs: [
-        "sdk-dir",
-        "api-versions-jars-dir",
-    ],
     api_levels_sdk_type: "system",
-    extensions_info_file: ":sdk-extensions-info",
     dists: [
         // Make the api-versions.xml file for the system API available in the
         // sdk build target.
@@ -1171,42 +1187,99 @@
     ],
 }
 
-// This module can be built with:
-// m out/soong/.intermediates/frameworks/base/api/api_versions_module_lib/android_common/metalava/api-versions.xml
-droidstubs {
-    name: "api_versions_module_lib",
-    srcs: [":android_module_stubs_current_with_test_libs{.jar}"],
-    generate_stubs: false,
-    api_levels_annotations_enabled: true,
+// Defaults for `droidstubs` modules that generate `api-versions.xml` files that
+// only include non-updatable code, i.e. for platform API only, not SDK
+// extensions.
+stubs_defaults {
+    name: "api_versions_non_updatable_defaults",
+    defaults_visibility: ["//visibility:private"],
+    defaults: ["api_versions_base_defaults"],
     // this only has the non-updatable portions of the module lib sdk,
     // which can reference classes from updatable apexes, so remove references to them
     // from this api_versions file.
     flags: ["--remove-missing-class-references-in-api-levels"],
-    api_levels_annotations_dirs: [
-        "sdk-dir",
-        "api-versions-jars-dir",
-    ],
-    api_levels_sdk_type: "module-lib",
     // extensions_info_file is purposefully omitted, because this module should just be
     // the non-updatable portions of the sdk, and extension sdks are updatable.
 }
 
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about only the non-updatable module-lib APIs and historic information about
+// all previous dessert and SDK extension releases. That historic information
+// may include information about APIs that were previously not-updatable which
+// have since become updatable.
+droidstubs {
+    name: "api_versions_module_lib",
+    defaults: ["api_versions_non_updatable_defaults"],
+    srcs: [":android_module_stubs_current_with_test_libs{.jar}"],
+    api_levels_sdk_type: "module-lib",
+}
+
+// Create a single jar containing the whole module-lib API surface.
+// This is needed because Metalava only consumes the first jar file it is given
+// and ignores the rest.
+java_library {
+    name: "android_module_stubs_complete_current_with_test_libs",
+    static_libs: [
+        "android_module_stubs_current_with_test_libs",
+        "framework-updatable-stubs-module_libs_api-exportable",
+    ],
+    defaults: ["android.jar_defaults"],
+    visibility: [
+        "//visibility:override",
+        "//visibility:private",
+    ],
+}
+
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about all the module-lib APIs, both updatable and non-updatable and historic
+// information about all previous dessert and SDK extension releases.
+droidstubs {
+    name: "api_versions_module_lib_complete",
+    defaults: ["api_versions_complete_defaults"],
+    srcs: [":android_module_stubs_complete_current_with_test_libs{.jar}"],
+    api_levels_sdk_type: "module-lib",
+}
+
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about only the non-updatable system-server APIs and historic information
+// about all previous dessert and SDK extension releases. That historic
+// information may include information about APIs that were previously
+// not-updatable which have since become updatable.
 droidstubs {
     name: "api_versions_system_server",
+    defaults: ["api_versions_non_updatable_defaults"],
     srcs: [":android_system_server_stubs_current_with_test_libs{.jar}"],
-    generate_stubs: false,
-    api_levels_annotations_enabled: true,
-    // this only has the non-updatable portions of the system server sdk,
-    // which can reference classes from updatable apexes, so remove references to them
-    // from this api_versions file.
-    flags: ["--remove-missing-class-references-in-api-levels"],
-    api_levels_annotations_dirs: [
-        "sdk-dir",
-        "api-versions-jars-dir",
-    ],
     api_levels_sdk_type: "system-server",
-    // extensions_info_file is purposefully omitted, because this module should just be
-    // the non-updatable portions of the sdk, and extension sdks are updatable.
+}
+
+// Create a single jar containing the whole system-server API surface.
+// This is needed because Metalava only consumes the first jar file it is given
+// and ignores the rest.
+java_library {
+    name: "android_system_server_stubs_complete_current_with_test_libs",
+    static_libs: [
+        "android_system_server_stubs_current_with_test_libs",
+        // system-server extends module-lib but libraries which only service-*
+        // libraries provided system-server APIs, so include module-lib APIs for
+        // the others, e.g. framework-* libraries.
+        "framework-updatable-stubs-module_libs_api-exportable",
+        "framework-updatable-stubs-system_server_api-exportable",
+    ],
+    defaults: ["android.jar_defaults"],
+    visibility: [
+        "//visibility:override",
+        "//visibility:private",
+    ],
+}
+
+// Produces an `api-versions.xml` file that includes up-to-date information
+// about all the system-server APIs, both updatable and non-updatable and
+// historic information about all previous dessert and SDK extension releases.
+droidstubs {
+    name: "api_versions_system_server_complete",
+    defaults: ["api_versions_complete_defaults"],
+    srcs: [":android_system_server_stubs_complete_current_with_test_libs{.jar}"],
+    api_levels_sdk_type: "system-server",
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/api/api.go b/api/api.go
index b31a26c..449fac6 100644
--- a/api/api.go
+++ b/api/api.go
@@ -386,6 +386,26 @@
 	ctx.CreateModule(java.LibraryFactory, &props)
 }
 
+func createMergedFrameworkSystemServerExportableStubs(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) {
+	// The user of this module compiles against the "core" SDK and against non-updatable bootclasspathModules,
+	// so remove to avoid dupes.
+	bootclasspathModules := removeAll(bootclasspath, core_libraries_modules)
+	bootclasspathModules = removeAll(bootclasspath, non_updatable_modules)
+	modules := append(
+		// Include all the module-lib APIs from the bootclasspath libraries.
+		transformArray(bootclasspathModules, "", ".stubs.exportable.module_lib"),
+		// Then add all the system-server APIs from the service-* libraries.
+		transformArray(system_server_classpath, "", ".stubs.exportable.system_server")...,
+	)
+	props := libraryProps{}
+	props.Name = proptools.StringPtr("framework-updatable-stubs-system_server_api-exportable")
+	props.Static_libs = modules
+	props.Sdk_version = proptools.StringPtr("system_server_current")
+	props.Visibility = []string{"//frameworks/base"}
+	props.Is_stubs_module = proptools.BoolPtr(true)
+	ctx.CreateModule(java.LibraryFactory, &props)
+}
+
 func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []string) {
 	props := fgProps{}
 	props.Name = proptools.StringPtr("all-modules-public-stubs-source")
@@ -531,6 +551,7 @@
 	createMergedSystemExportableStubs(ctx, bootclasspath)
 	createMergedTestExportableStubsForNonUpdatableModules(ctx)
 	createMergedFrameworkModuleLibExportableStubs(ctx, bootclasspath)
+	createMergedFrameworkSystemServerExportableStubs(ctx, bootclasspath, system_server_classpath)
 
 	createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath)
 
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 77b74e9..5adcd93 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -707,11 +707,11 @@
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglDestroySurface(mDisplay, mSurface);
 
-    mFlingerSurfaceControl->updateDefaultBufferSize(newWidth, newHeight);
     const auto limitedSize = limitSurfaceSize(newWidth, newHeight);
     mWidth = limitedSize.width;
     mHeight = limitedSize.height;
 
+    mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight);
     EGLConfig config = getEglConfig(mDisplay);
     EGLSurface surface = eglCreateWindowSurface(mDisplay, config, mFlingerSurface.get(), nullptr);
     if (eglMakeCurrent(mDisplay, surface, surface, mContext) == EGL_FALSE) {
diff --git a/cmds/bootanimation/FORMAT.md b/cmds/bootanimation/FORMAT.md
index 01e8fe1..da8331a 100644
--- a/cmds/bootanimation/FORMAT.md
+++ b/cmds/bootanimation/FORMAT.md
@@ -126,7 +126,7 @@
 Use `zopflipng` if you have it, otherwise `pngcrush` will do. e.g.:
 
     for fn in *.png ; do
-        zopflipng -m ${fn}s ${fn}s.new && mv -f ${fn}s.new ${fn}
+        zopflipng -m ${fn} ${fn}.new && mv -f ${fn}.new ${fn}
         # or: pngcrush -q ....
     done
 
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 8b8d361..a142450 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -134,8 +134,9 @@
     return env;
 }
 
-std::unique_ptr<Device> Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
-                                     uint16_t bus, const std::vector<uint8_t>& descriptor,
+std::unique_ptr<Device> Device::open(int32_t id, const char* name, const char* uniq, int32_t vid,
+                                     int32_t pid, uint16_t bus,
+                                     const std::vector<uint8_t>& descriptor,
                                      std::unique_ptr<DeviceCallback> callback) {
     size_t size = descriptor.size();
     if (size > HID_MAX_DESCRIPTOR_SIZE) {
@@ -152,8 +153,7 @@
     struct uhid_event ev = {};
     ev.type = UHID_CREATE2;
     strlcpy(reinterpret_cast<char*>(ev.u.create2.name), name, sizeof(ev.u.create2.name));
-    std::string uniq = android::base::StringPrintf("Id: %d", id);
-    strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq.c_str(), sizeof(ev.u.create2.uniq));
+    strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq, sizeof(ev.u.create2.uniq));
     memcpy(&ev.u.create2.rd_data, descriptor.data(), size * sizeof(ev.u.create2.rd_data[0]));
     ev.u.create2.rd_size = size;
     ev.u.create2.bus = bus;
@@ -314,19 +314,31 @@
     return data;
 }
 
-static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid,
-                        jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) {
+static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jstring rawUniq, jint id,
+                        jint vid, jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) {
     ScopedUtfChars name(env, rawName);
     if (name.c_str() == nullptr) {
         return 0;
     }
 
+    std::string uniq;
+    if (rawUniq != nullptr) {
+        uniq = ScopedUtfChars(env, rawUniq);
+    } else {
+        uniq = android::base::StringPrintf("Id: %d", id);
+    }
+
+    if (uniq.c_str() == nullptr) {
+        return 0;
+    }
+
     std::vector<uint8_t> desc = getData(env, rawDescriptor);
 
     std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
 
     std::unique_ptr<uhid::Device> d =
-            uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()), vid, pid, bus, desc,
+            uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()),
+                               reinterpret_cast<const char*>(uniq.c_str()), vid, pid, bus, desc,
                                std::move(cb));
     return reinterpret_cast<jlong>(d.release());
 }
@@ -370,7 +382,7 @@
 
 static JNINativeMethod sMethods[] = {
         {"nativeOpenDevice",
-         "(Ljava/lang/String;IIII[B"
+         "(Ljava/lang/String;Ljava/lang/String;IIII[B"
          "Lcom/android/commands/hid/Device$DeviceCallback;)J",
          reinterpret_cast<void*>(openDevice)},
         {"nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport)},
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 9c6060d..bc7a909 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -42,8 +42,9 @@
 
 class Device {
 public:
-    static std::unique_ptr<Device> open(int32_t id, const char* name, int32_t vid, int32_t pid,
-                                        uint16_t bus, const std::vector<uint8_t>& descriptor,
+    static std::unique_ptr<Device> open(int32_t id, const char* name, const char* uniq, int32_t vid,
+                                        int32_t pid, uint16_t bus,
+                                        const std::vector<uint8_t>& descriptor,
                                         std::unique_ptr<DeviceCallback> callback);
 
     ~Device();
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index 0415037..4e8adc3 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -71,6 +71,7 @@
 
     private static native long nativeOpenDevice(
             String name,
+            String uniq,
             int id,
             int vid,
             int pid,
@@ -89,6 +90,7 @@
     public Device(
             int id,
             String name,
+            String uniq,
             int vid,
             int pid,
             int bus,
@@ -113,8 +115,9 @@
         } else {
             args.arg1 = id + ":" + vid + ":" + pid;
         }
-        args.arg2 = descriptor;
-        args.arg3 = report;
+        args.arg2 = uniq;
+        args.arg3 = descriptor;
+        args.arg4 = report;
         mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget();
         mTimeToSend = SystemClock.uptimeMillis();
     }
@@ -167,11 +170,12 @@
                     mPtr =
                             nativeOpenDevice(
                                     (String) args.arg1,
+                                    (String) args.arg2,
                                     args.argi1,
                                     args.argi2,
                                     args.argi3,
                                     args.argi4,
-                                    (byte[]) args.arg2,
+                                    (byte[]) args.arg3,
                                     new DeviceCallback());
                     pauseEvents();
                     break;
diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java
index 3efb797..3b02279 100644
--- a/cmds/hid/src/com/android/commands/hid/Event.java
+++ b/cmds/hid/src/com/android/commands/hid/Event.java
@@ -56,6 +56,7 @@
     private int mId;
     private String mCommand;
     private String mName;
+    private String mUniq;
     private byte[] mDescriptor;
     private int mVid;
     private int mPid;
@@ -78,6 +79,10 @@
         return mName;
     }
 
+    public String getUniq() {
+        return mUniq;
+    }
+
     public byte[] getDescriptor() {
         return mDescriptor;
     }
@@ -116,8 +121,9 @@
 
     public String toString() {
         return "Event{id=" + mId
-            + ", command=" + String.valueOf(mCommand)
-            + ", name=" + String.valueOf(mName)
+            + ", command=" + mCommand
+            + ", name=" + mName
+            + ", uniq=" + mUniq
             + ", descriptor=" + Arrays.toString(mDescriptor)
             + ", vid=" + mVid
             + ", pid=" + mPid
@@ -149,6 +155,10 @@
             mEvent.mName = name;
         }
 
+        public void setUniq(String uniq) {
+            mEvent.mUniq = uniq;
+        }
+
         public void setDescriptor(byte[] descriptor) {
             mEvent.mDescriptor = descriptor;
         }
@@ -247,6 +257,9 @@
                             case "name":
                                 eb.setName(mReader.nextString());
                                 break;
+                            case "uniq":
+                                eb.setUniq(mReader.nextString());
+                                break;
                             case "vid":
                                 eb.setVid(readInt());
                                 break;
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
index 2db791fe..5ebfd95 100644
--- a/cmds/hid/src/com/android/commands/hid/Hid.java
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -117,8 +117,17 @@
                     "Tried to send command \"" + e.getCommand() + "\" to an unregistered device!");
         }
         int id = e.getId();
-        Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(),
-                e.getDescriptor(), e.getReport(), e.getFeatureReports(), e.getOutputs());
+        Device d = new Device(
+                id,
+                e.getName(),
+                e.getUniq(),
+                e.getVendorId(),
+                e.getProductId(),
+                e.getBus(),
+                e.getDescriptor(),
+                e.getReport(),
+                e.getFeatureReports(),
+                e.getOutputs());
         mDevices.append(id, d);
     }
 
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
index 488292d..f726361 100644
--- a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -292,13 +292,17 @@
         int childCount = node.getChildCount();
         for (int x = 0; x < childCount; x++) {
             AccessibilityNodeInfo childNode = node.getChild(x);
-
+            if (childNode == null) {
+                continue;
+            }
             if (!safeCharSeqToString(childNode.getContentDescription()).isEmpty()
-                    || !safeCharSeqToString(childNode.getText()).isEmpty())
+                    || !safeCharSeqToString(childNode.getText()).isEmpty()) {
                 return true;
+            }
 
-            if (childNafCheck(childNode))
+            if (childNafCheck(childNode)) {
                 return true;
+            }
         }
         return false;
     }
diff --git a/config/Android.bp b/config/Android.bp
index adce203..c9948c3 100644
--- a/config/Android.bp
+++ b/config/Android.bp
@@ -33,7 +33,7 @@
     name: "preloaded-classes",
     src: "preloaded-classes",
     filename: "preloaded-classes",
-    installable: false,
+    no_full_install: true,
 }
 
 filegroup {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 2a7dbab..e7e3a85 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -364,12 +364,12 @@
     public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14;
 
     /**
-     * The user has performed an down and left gesture on the touch screen.
+     * The user has performed a down and left gesture on the touch screen.
      */
     public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15;
 
     /**
-     * The user has performed an down and right gesture on the touch screen.
+     * The user has performed a down and right gesture on the touch screen.
      */
     public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 7ee3413..497d47a 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2015,7 +2015,7 @@
      *     null for no callback
      * @param handler {@link Handler} identifying the callback thread,
      *     null for the main thread
-     * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated wether it
+     * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated whether it
      * succeeded.
      * @hide
      */
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 712f3e5..02f00ba 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -60,6 +60,9 @@
 # ComponentCaller
 per-file ComponentCaller.java = file:COMPONENT_CALLER_OWNERS
 
+# DreamManager
+per-file DreamManager.java = file:/DREAM_MANAGER_OWNERS
+
 # GrammaticalInflectionManager
 per-file *GrammaticalInflection* = file:/services/core/java/com/android/server/grammaticalinflection/OWNERS
 
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index b303ea6..4df67d5 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
      namespace: "system_performance"
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 35ce102..649b812 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.admin.flags"
+container: "system"
 
 flag {
   name: "policy_engine_migration_v2_enabled"
@@ -43,6 +44,16 @@
 }
 
 flag {
+  name: "hsum_unlock_notification_fix"
+  namespace: "enterprise"
+  description: "Using the right userId when starting the work profile unlock flow "
+  bug: "327350831"
+  metadata {
+      purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "dumpsys_policy_engine_migration_enabled"
   namespace: "enterprise"
   description: "Update DumpSys to include information about migrated APIs in DPE"
diff --git a/core/java/android/app/grammatical_inflection_manager.aconfig b/core/java/android/app/grammatical_inflection_manager.aconfig
index 989ce61..1a6bb66 100644
--- a/core/java/android/app/grammatical_inflection_manager.aconfig
+++ b/core/java/android/app/grammatical_inflection_manager.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
     name: "system_terms_of_address_enabled"
diff --git a/core/java/android/app/network-policy.aconfig b/core/java/android/app/network-policy.aconfig
index 88f386f..e7b02a7 100644
--- a/core/java/android/app/network-policy.aconfig
+++ b/core/java/android/app/network-policy.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
      namespace: "backstage_power"
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index fb0edb9..30ae689 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
   name: "modes_api"
diff --git a/core/java/android/app/pinner-client.aconfig b/core/java/android/app/pinner-client.aconfig
index b60ad9e..1c9b653e 100644
--- a/core/java/android/app/pinner-client.aconfig
+++ b/core/java/android/app/pinner-client.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
      namespace: "system_performance"
diff --git a/core/java/android/app/prediction/OWNERS b/core/java/android/app/prediction/OWNERS
index fe012da..73168fb 100644
--- a/core/java/android/app/prediction/OWNERS
+++ b/core/java/android/app/prediction/OWNERS
@@ -1,2 +1,4 @@
+pinyaoting@google.com
+hyunyoungs@google.com
 adamcohen@google.com
 sunnygoyal@google.com
diff --git a/core/java/android/app/smartspace/flags.aconfig b/core/java/android/app/smartspace/flags.aconfig
index 12af888..b763a27 100644
--- a/core/java/android/app/smartspace/flags.aconfig
+++ b/core/java/android/app/smartspace/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.smartspace.flags"
+container: "system"
 
 flag {
   name: "remote_views"
diff --git a/core/java/android/app/usage/flags.aconfig b/core/java/android/app/usage/flags.aconfig
index a611255..005541c 100644
--- a/core/java/android/app/usage/flags.aconfig
+++ b/core/java/android/app/usage/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.usage"
+container: "system"
 
 flag {
     name: "user_interaction_type_api"
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index c95b864..d3ac2c8 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.appwidget.flags"
+container: "system"
 
 flag {
   name: "generated_previews"
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 9e410b8..cdfd088 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.companion"
+container: "system"
 
 flag {
     name: "new_association_builder"
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index ce2490b..64497d4 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -8,6 +8,7 @@
 # instead.
 
 package: "android.companion.virtual.flags"
+container: "system"
 
 flag {
   name: "enable_native_vdm"
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index d26890f..0c35b9d 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 package: "android.companion.virtualdevice.flags"
+container: "system"
 
 flag {
      namespace: "virtual_devices"
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 7f782ab..73c685f 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.content.pm"
+container: "system"
 
 flag {
     name: "quarantined_enabled"
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 9a1796f..b5292879 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -1,4 +1,5 @@
 package: "android.multiuser"
+container: "system"
 
 flag {
     name: "save_global_and_guest_restrictions_on_system_user_xml"
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 3a00d91..31a1184 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.content.res"
+container: "system"
 
 flag {
     name: "default_locale"
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index f876eeb..fab8e1a 100644
--- a/core/java/android/credentials/flags.aconfig
+++ b/core/java/android/credentials/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.credentials.flags"
+container: "system"
 
 flag {
     namespace: "credential_manager"
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index 62a5123..899e25f 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.database.sqlite"
+container: "system"
 
 flag {
      name: "sqlite_apis_35"
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index a7cf711..286c1a4 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.biometrics"
+container: "system"
 
 flag {
     name: "last_authentication_time"
diff --git a/core/java/android/hardware/flags/overlayproperties_flags.aconfig b/core/java/android/hardware/flags/overlayproperties_flags.aconfig
index c6a352e..4a81c80 100644
--- a/core/java/android/hardware/flags/overlayproperties_flags.aconfig
+++ b/core/java/android/hardware/flags/overlayproperties_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.flags"
+container: "system"
 
 flag {
     name: "overlayproperties_class_api"
diff --git a/core/java/android/hardware/hdmi/OWNERS b/core/java/android/hardware/hdmi/OWNERS
index 6952e5d..f7a22f5 100644
--- a/core/java/android/hardware/hdmi/OWNERS
+++ b/core/java/android/hardware/hdmi/OWNERS
@@ -3,3 +3,4 @@
 include /services/core/java/com/android/server/display/OWNERS
 
 quxiangfang@google.com
+donpaul@google.com
\ No newline at end of file
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index 362fe78..31ea978 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.hardware.input"
+container: "system"
 
 # Project link: https://gantry.corp.google.com/projects/android_platform_input_native/changes
 
diff --git a/core/java/android/hardware/radio/flags.aconfig b/core/java/android/hardware/radio/flags.aconfig
index dbc1a4b..90dfd1d 100644
--- a/core/java/android/hardware/radio/flags.aconfig
+++ b/core/java/android/hardware/radio/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.radio"
+container: "system"
 
 flag {
     name: "hd_radio_improved"
diff --git a/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig b/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
index 63ae28f..3e49af6 100644
--- a/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
+++ b/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.usb.flags"
+container: "system"
 
 flag {
     name: "enable_usb_data_compliance_warning"
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 594ec18..334b231 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -173,6 +173,12 @@
     public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby";
     /** @hide */
     public static final String FIREWALL_CHAIN_NAME_BACKGROUND = "background";
+    /** @hide */
+    public static final String FIREWALL_CHAIN_NAME_METERED_ALLOW = "metered_allow";
+    /** @hide */
+    public static final String FIREWALL_CHAIN_NAME_METERED_DENY_USER = "metered_deny_user";
+    /** @hide */
+    public static final String FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN = "metered_deny_admin";
 
     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
 
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 3544a69..048c50e 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.net.platform.flags"
+container: "system"
 
 # This file contains aconfig flags used from platform code
 # Flags used for module APIs must be in aconfig files under each modules
diff --git a/core/java/android/net/thread/flags.aconfig b/core/java/android/net/thread/flags.aconfig
index ef798ad..afb982b 100644
--- a/core/java/android/net/thread/flags.aconfig
+++ b/core/java/android/net/thread/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.net.thread.platform.flags"
+container: "system"
 
 # This file contains aconfig flags used from platform code
 # Flags used for module APIs must be in aconfig files under each modules
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 6fde398..d4d1ed2 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.net.vcn"
+container: "system"
 
 flag {
     name: "safe_mode_config"
@@ -37,6 +38,16 @@
 }
 
 flag{
+    name: "enforce_main_user"
+    namespace: "vcn"
+    description: "Enforce main user to make VCN HSUM compatible"
+    bug: "310310661"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag{
     name: "handle_seq_num_leap"
     namespace: "vcn"
     description: "Do not report bad network when there is a suspected sequence number leap"
@@ -44,4 +55,14 @@
     metadata {
       purpose: PURPOSE_BUGFIX
     }
+}
+
+flag{
+    name: "allow_disable_ipsec_loss_detector"
+    namespace: "vcn"
+    description: "Allow disabling IPsec packet loss detector"
+    bug: "336638836"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 5056557..bb89e07 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -17,8 +17,11 @@
 package android.os;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 
+import java.io.IOException;
 import java.util.Map;
 
 /**
@@ -113,5 +116,20 @@
     @TestApi
     public static native Long getTargetFrameworkCompatibilityMatrixVersion();
 
+    /**
+     * Executes a shell command using shell user identity, and return the standard output in string.
+     *
+     * @hide
+     */
+    private static @Nullable String runShellCommand(@NonNull String command) throws IOException {
+        var activityThread = ActivityThread.currentActivityThread();
+        var instrumentation = activityThread.getInstrumentation();
+        var automation = instrumentation.getUiAutomation();
+        var pfd = automation.executeShellCommand(command);
+        try (var is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+            return new String(is.readAllBytes());
+        }
+    }
+
     private VintfObject() {}
 }
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 4468e25..960bda3 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.os"
+container: "system"
 
 flag {
     name: "android_os_build_vanilla_ice_cream"
diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig
index 437668c..e47b943 100644
--- a/core/java/android/os/vibrator/flags.aconfig
+++ b/core/java/android/os/vibrator/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.os.vibrator"
+container: "system"
 
 flag {
     namespace: "haptics"
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
index d2f4b50..857bacd 100644
--- a/core/java/android/permission/OWNERS
+++ b/core/java/android/permission/OWNERS
@@ -1,14 +1,13 @@
 # Bug component: 137825
 
-augale@google.com
 evanseverson@google.com
 fayey@google.com
 jaysullivan@google.com
 joecastro@google.com
-kvakil@google.com
 mrulhania@google.com
 ntmyren@google.com
 rmacgregor@google.com
 theianchen@google.com
 yutingfang@google.com
 zhanghai@google.com
+kiranmr@google.com
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index a8ab391..fece5d3 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.permission.flags"
+container: "system"
 
 flag {
   name: "device_aware_permission_apis_enabled"
diff --git a/core/java/android/provider/flags.aconfig b/core/java/android/provider/flags.aconfig
index 3dd7692..32a6333 100644
--- a/core/java/android/provider/flags.aconfig
+++ b/core/java/android/provider/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.provider"
+container: "system"
 
 flag {
     name: "system_settings_default"
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 6aa956b..aadc8db 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.security"
+container: "system"
 
 flag {
     name: "certificate_transparency_configuration"
@@ -78,8 +79,15 @@
 }
 
 flag {
-  name: "report_primary_auth_attempts"
-  namespace: "biometrics"
-  description: "Report primary auth attempts from LockSettingsService"
-  bug: "285053096"
+    name: "report_primary_auth_attempts"
+    namespace: "biometrics"
+    description: "Report primary auth attempts from LockSettingsService"
+    bug: "285053096"
+}
+
+flag {
+    name: "dump_attestation_verifications"
+    namespace: "hardware_backed_security"
+    description: "Add a dump capability for attestation_verification service"
+    bug: "335498868"
 }
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 0bae459..85ac166 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.security"
+container: "system"
 
 flag {
     name: "extend_ecm_to_all_settings"
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index 5978383..38fff09 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.chooser"
+container: "system"
 
 flag {
   name: "support_nfc_resolver"
diff --git a/core/java/android/service/controls/flags/flags.aconfig b/core/java/android/service/controls/flags/flags.aconfig
index 3a28844..881a0ec 100644
--- a/core/java/android/service/controls/flags/flags.aconfig
+++ b/core/java/android/service/controls/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.controls.flags"
+container: "system"
 
 flag {
     name: "home_panel_dream"
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 91a713e..2e16a03 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.dreams"
+container: "system"
 
 flag {
   name: "dream_overlay_host"
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index 2a05c84..71bee65 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.notification"
+container: "system"
 
 flag {
   name: "ranking_update_ashmem"
diff --git a/core/java/android/service/voice/flags/flags.aconfig b/core/java/android/service/voice/flags/flags.aconfig
index b596666..9a818bf 100644
--- a/core/java/android/service/voice/flags/flags.aconfig
+++ b/core/java/android/service/voice/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.voice.flags"
+container: "system"
 
 flag {
     name: "allow_training_data_egress_from_hds"
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index a1885ae..946a8c0 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.text.flags"
+container: "system"
 
 flag {
   name: "vendor_custom_locale_fallback"
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index c6e8844..9e23a4f 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.tracing"
+container: "system"
 
 flag {
     name: "perfetto_transition_tracing"
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 064bc69..5c49e24 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -129,7 +129,7 @@
         }
         ViewGroup effective = null;
         ViewParent nextParent = focused.getParent();
-        do {
+        while (nextParent instanceof ViewGroup) {
             if (nextParent == root) {
                 return effective != null ? effective : root;
             }
@@ -143,7 +143,7 @@
                 effective = vg;
             }
             nextParent = nextParent.getParent();
-        } while (nextParent instanceof ViewGroup);
+        }
         return root;
     }
 
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 0cc19fb..9e2ba9d 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.accessibility"
+container: "system"
 
 # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
 
diff --git a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
index 3c15518..416a877 100644
--- a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
+++ b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.contentcapture.flags"
+container: "system"
 
 flag {
     name: "run_on_background_thread_enabled"
diff --git a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
index 2a3008a..321a887 100644
--- a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
+++ b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.contentprotection.flags"
+container: "system"
 
 flag {
     name: "blocklist_update_enabled"
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index 0aa516e..dd8f5d0 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.flags"
+container: "system"
 
 flag {
     name: "view_velocity_api"
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index d1d871c2..3f018f8 100644
--- a/core/java/android/view/flags/scroll_feedback_flags.aconfig
+++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.flags"
+container: "system"
 
 flag {
     namespace: "toolkit"
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index dc6aa6c..6f4bf24 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.inputmethod"
+container: "system"
 
 flag {
     name: "refactor_insets_controller"
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index a07141b..b7ee0b8 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -520,6 +520,13 @@
      * To cancel the request, call <code>filePathCallback.onReceiveValue(null)</code> and
      * return {@code true}.
      *
+     * <p class="note"><b>Note:</b> WebView does not enforce any restrictions on
+     * the chosen file(s). WebView can access all files that your app can access.
+     * In case the file(s) are chosen through an untrusted source such as a third-party
+     * app, it is your own app's responsibility to check what the returned Uris
+     * refer to before calling the <code>filePathCallback</code>. See
+     * {@link #createIntent} and {@link #parseResult} for more details.</p>
+     *
      * @param webView The WebView instance that is initiating the request.
      * @param filePathCallback Invoke this callback to supply the list of paths to files to upload,
      *                         or {@code null} to cancel. Must only be called if the
@@ -556,6 +563,15 @@
          * Parse the result returned by the file picker activity. This method should be used with
          * {@link #createIntent}. Refer to {@link #createIntent} for how to use it.
          *
+         * <p class="note"><b>Note:</b> The intent returned by the file picker activity
+         * should be treated as untrusted. A third-party app handling the implicit
+         * intent created by {@link #createIntent} might return Uris that the third-party
+         * app itself does not have access to, such as your own app's sensitive data files.
+         * WebView does not enforce any restrictions on the returned Uris. It is the
+         * app's responsibility to ensure that the untrusted source (such as a third-party
+         * app) has access the Uris it has returned and that the Uris are not pointing
+         * to any sensitive data files.</p>
+         *
          * @param resultCode the integer result code returned by the file picker activity.
          * @param data the intent returned by the file picker activity.
          * @return the Uris of selected file(s) or {@code null} if the resultCode indicates
@@ -618,6 +634,12 @@
          *   WebChromeClient#onShowFileChooser}</li>
          * </ol>
          *
+         * <p class="note"><b>Note:</b> The created intent may be handled by
+         * third-party applications on device. The received result must be treated
+         * as untrusted as it can contain Uris pointing to your own app's sensitive
+         * data files. Your app should check the resultant Uris in {@link #parseResult}
+         * before calling the <code>filePathCallback</code>.</p>
+         *
          * @return an Intent that supports basic file chooser sources.
          */
         public abstract Intent createIntent();
diff --git a/core/java/android/widget/flags/differential_motion_fling_flags.aconfig b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
index 79cfe56..a0a391e 100644
--- a/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
+++ b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.widget.flags"
+container: "system"
 
 flag {
     namespace: "toolkit"
diff --git a/core/java/android/window/flags/accessibility.aconfig b/core/java/android/window/flags/accessibility.aconfig
index d467be6..bab9ac9 100644
--- a/core/java/android/window/flags/accessibility.aconfig
+++ b/core/java/android/window/flags/accessibility.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
   name: "do_not_check_intersection_when_non_magnifiable_window_transitions"
diff --git a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
index 727bff4..d4bf2ed 100644
--- a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
+++ b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
   name: "allows_screen_size_decoupled_from_status_bar_and_cutout"
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index ad0e9a4..d0870d3 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
     name: "bal_require_opt_in_by_pending_intent_creator"
diff --git a/core/java/android/window/flags/wallpaper_manager.aconfig b/core/java/android/window/flags/wallpaper_manager.aconfig
index f03c993..a8645ab 100644
--- a/core/java/android/window/flags/wallpaper_manager.aconfig
+++ b/core/java/android/window/flags/wallpaper_manager.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
     name: "always_update_wallpaper_permission"
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index 56df493..6c6daf8 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 # Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
 
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 07beb11..af6105d 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
   name: "nav_bar_transparent_by_default"
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 933cc49..7688c17 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 # Project link: https://gantry.corp.google.com/projects/android_platform_windowing_sdk/changes
 
diff --git a/core/java/com/android/internal/content/om/OverlayConfigParser.java b/core/java/com/android/internal/content/om/OverlayConfigParser.java
index faaf7d5..8132652 100644
--- a/core/java/com/android/internal/content/om/OverlayConfigParser.java
+++ b/core/java/com/android/internal/content/om/OverlayConfigParser.java
@@ -24,6 +24,8 @@
 import android.content.pm.PackagePartitions.SystemPartition;
 import android.os.Build;
 import android.os.FileUtils;
+import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Xml;
@@ -241,6 +243,18 @@
         }
     }
 
+    @FunctionalInterface
+    public interface SysPropWrapper{
+        /**
+         * Get system property
+         *
+         * @param property the key to look up.
+         *
+         * @return The property value if found, empty string otherwise.
+         */
+        String get(String property);
+    }
+
     /**
      * Retrieves overlays configured within the partition in increasing priority order.
      *
@@ -320,6 +334,76 @@
     }
 
     /**
+     * Expand the property inside a rro configuration path.
+     *
+     * A RRO configuration can contain a property, this method expands
+     * the property to its value.
+     *
+     * Only read only properties allowed, prefixed with ro. Other
+     * properties will raise exception.
+     *
+     * Only a single property in the path is allowed.
+     *
+     * Example "${ro.boot.hardware.sku}/config.xml" would expand to
+     *     "G020N/config.xml"
+     *
+     * @param configPath path to expand
+     * @param sysPropWrapper method used for reading properties
+     *
+     * @return The expanded path. Returns null if configPath is null.
+     */
+    @VisibleForTesting
+    public static String expandProperty(String configPath,
+            SysPropWrapper sysPropWrapper) {
+        if (configPath == null) {
+            return null;
+        }
+
+        int propStartPos = configPath.indexOf("${");
+        if (propStartPos == -1) {
+            // No properties inside the string, return as is
+            return configPath;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        sb.append(configPath.substring(0, propStartPos));
+
+        // Read out the end position
+        int propEndPos = configPath.indexOf("}", propStartPos);
+        if (propEndPos == -1) {
+            throw new IllegalStateException("Malformed property, unmatched braces, in: "
+                    + configPath);
+        }
+
+        // Confirm that there is only one property inside the string
+        if (configPath.indexOf("${", propStartPos + 2) != -1) {
+            throw new IllegalStateException("Only a single property supported in path: "
+                    + configPath);
+        }
+
+        final String propertyName = configPath.substring(propStartPos + 2, propEndPos);
+        if (!propertyName.startsWith("ro.")) {
+            throw new IllegalStateException("Only read only properties can be used when "
+                    + "merging RRO config files: " + propertyName);
+        }
+        final String propertyValue = sysPropWrapper.get(propertyName);
+        if (TextUtils.isEmpty(propertyValue)) {
+            throw new IllegalStateException("Property is empty or doesn't exist: " + propertyName);
+        }
+        Log.d(TAG, String.format("Using property in overlay config path: \"%s\"", propertyName));
+        sb.append(propertyValue);
+
+        // propEndPos points to '}', need to step to next character, might be outside of string
+        propEndPos = propEndPos + 1;
+        // Append the remainder, if exists
+        if (propEndPos < configPath.length()) {
+            sb.append(configPath.substring(propEndPos));
+        }
+
+        return sb.toString();
+    }
+
+    /**
      * Parses a <merge> tag within an overlay configuration file.
      *
      * Merge tags allow for other configuration files to be "merged" at the current parsing
@@ -331,10 +415,21 @@
             @Nullable OverlayScanner scanner,
             @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos,
             @NonNull ParsingContext parsingContext) {
-        final String path = parser.getAttributeValue(null, "path");
+        final String path;
+
+        try {
+            SysPropWrapper sysPropWrapper = p -> {
+                return SystemProperties.get(p, "");
+            };
+            path = expandProperty(parser.getAttributeValue(null, "path"), sysPropWrapper);
+        } catch (IllegalStateException e) {
+            throw new IllegalStateException(String.format("<merge> path expand error in %s at %s",
+                    configFile, parser.getPositionDescription()), e);
+        }
+
         if (path == null) {
-            throw new IllegalStateException(String.format("<merge> without path in %s at %s"
-                    + configFile, parser.getPositionDescription()));
+            throw new IllegalStateException(String.format("<merge> without path in %s at %s",
+                    configFile, parser.getPositionDescription()));
         }
 
         if (path.startsWith("/")) {
diff --git a/core/java/com/android/internal/foldables/Android.bp b/core/java/com/android/internal/foldables/Android.bp
index f1d06da..53a9be5 100644
--- a/core/java/com/android/internal/foldables/Android.bp
+++ b/core/java/com/android/internal/foldables/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "fold_lock_setting_flags",
     package: "com.android.internal.foldables.flags",
+    container: "system",
     srcs: [
         "fold_lock_setting_flags.aconfig",
     ],
diff --git a/core/java/com/android/internal/foldables/fold_lock_setting_flags.aconfig b/core/java/com/android/internal/foldables/fold_lock_setting_flags.aconfig
index 44f436ea..c00a2b5 100644
--- a/core/java/com/android/internal/foldables/fold_lock_setting_flags.aconfig
+++ b/core/java/com/android/internal/foldables/fold_lock_setting_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.internal.foldables.flags"
+container: "system"
 
 flag {
     name: "fold_lock_setting_enabled"
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 9fc7ddb..0e5049e 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -1911,12 +1911,16 @@
             } else if (parser.getName().equals("package")) {
                 final TypedArray sa = res.obtainAttributes(parser,
                         R.styleable.AndroidManifestQueriesPackage);
-                final String packageName = sa.getNonConfigurationString(
-                        R.styleable.AndroidManifestQueriesPackage_name, 0);
-                if (TextUtils.isEmpty(packageName)) {
-                    return input.error("Package name is missing from package tag.");
+                try {
+                    final String packageName = sa.getNonConfigurationString(
+                            R.styleable.AndroidManifestQueriesPackage_name, 0);
+                    if (TextUtils.isEmpty(packageName)) {
+                        return input.error("Package name is missing from package tag.");
+                    }
+                    pkg.addQueriesPackage(packageName.intern());
+                } finally {
+                    sa.recycle();
                 }
-                pkg.addQueriesPackage(packageName.intern());
             } else if (parser.getName().equals("provider")) {
                 final TypedArray sa = res.obtainAttributes(parser,
                         R.styleable.AndroidManifestQueriesProvider);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 8566263..e08443b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -861,7 +861,7 @@
         final MenuHelper helper;
         final boolean isPopup = !Float.isNaN(x) && !Float.isNaN(y);
         if (isPopup) {
-            helper = mWindow.mContextMenu.showPopup(getContext(), originalView, x, y);
+            helper = mWindow.mContextMenu.showPopup(originalView.getContext(), originalView, x, y);
         } else {
             helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken());
         }
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
new file mode 100644
index 0000000..1340156
--- /dev/null
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.ravenwood;
+
+/**
+ * Class to interact with the Ravenwood environment.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+public class RavenwoodEnvironment {
+    private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment();
+
+    private RavenwoodEnvironment() {
+    }
+
+    /**
+     * @return the singleton instance.
+     */
+    public static RavenwoodEnvironment getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * USE IT SPARINGLY! Returns true if it's running on Ravenwood, hostside test environment.
+     *
+     * <p>Using this allows code to behave differently on a real device and on Ravenwood, but
+     * generally speaking, that's a bad idea because we want the test target code to behave
+     * differently.
+     *
+     * <p>This should be only used when different behavior is absolutely needed.
+     *
+     * <p>If someone needs it without having access to the SDK, the following hack would work too.
+     * <code>System.getProperty("java.class.path").contains("ravenwood")</code>
+     */
+    @android.ravenwood.annotation.RavenwoodReplace
+    public boolean isRunningOnRavenwood() {
+        return false;
+    }
+
+    public boolean isRunningOnRavenwood$ravenwood() {
+        return true;
+    }
+}
diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java
index 6cf241e..ddbb586 100644
--- a/core/java/com/android/internal/util/ProcFileReader.java
+++ b/core/java/com/android/internal/util/ProcFileReader.java
@@ -89,6 +89,12 @@
         mTail -= count;
         if (mTail == 0) {
             fillBuf();
+
+            if (mTail > 0 && mBuffer[0] == ' ') {
+                // After filling the buffer, it contains more consecutive
+                // delimiters that need to be skipped.
+                consumeBuf(0);
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 66b0158..0734e68 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -886,9 +886,16 @@
             cellState.activationAnimator.cancel();
         }
         AnimatorSet animatorSet = new AnimatorSet();
+
+        // When running the line end animation (see doc for createLineEndAnimation), if cell is in:
+        // - activate state - use finger position at the time of hit detection
+        // - deactivate state - use current position where the end was last during initial animation
+        // Note that deactivate state will only come if mKeepDotActivated is themed true.
+        final float startX = activate == CELL_ACTIVATE ? mInProgressX : cellState.lineEndX;
+        final float startY = activate == CELL_ACTIVATE ? mInProgressY : cellState.lineEndY;
         AnimatorSet.Builder animatorSetBuilder = animatorSet
                 .play(createLineDisappearingAnimation())
-                .with(createLineEndAnimation(cellState, mInProgressX, mInProgressY,
+                .with(createLineEndAnimation(cellState, startX, startY,
                         getCenterXForColumn(cell.column), getCenterYForRow(cell.row)));
         if (mDotSize != mDotSizeActivated) {
             animatorSetBuilder.with(createDotRadiusAnimation(cellState));
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 6412ddb..3024b94 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -478,4 +478,8 @@
         "libnativehelper",
         "libvintf",
     ],
+
+    required: [
+        "vintf",
+    ],
 }
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 8dc9d0a..7a4854b 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -32,6 +32,8 @@
 static jmethodID gHashMapPut;
 static jclass gLongClazz;
 static jmethodID gLongValueOf;
+static jclass gVintfObjectClazz;
+static jmethodID gRunCommand;
 
 namespace android {
 
@@ -47,6 +49,56 @@
 using vintf::Vndk;
 using vintf::CheckFlags::ENABLE_ALL_CHECKS;
 
+// Instead of VintfObject::GetXxx(), we construct
+// HalManifest/CompatibilityMatrix objects by calling `vintf` through
+// UiAutomation.executeShellCommand() so that the commands are executed
+// using shell identity. Otherwise, we would need to allow "apps" to access
+// files like apex-info-list.xml which we don't want to open to apps.
+// This is okay because VintfObject is @TestApi and only used in CTS tests.
+
+static std::string runCmd(JNIEnv* env, const char* cmd) {
+    jstring jstr = (jstring)env->CallStaticObjectMethod(gVintfObjectClazz, gRunCommand,
+                                                        env->NewStringUTF(cmd));
+    std::string output;
+    if (jstr) {
+        auto cstr = env->GetStringUTFChars(jstr, nullptr);
+        output = std::string(cstr);
+        env->ReleaseStringUTFChars(jstr, cstr);
+    } else {
+        LOG(WARNING) << "Failed to run " << cmd;
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+    }
+    return output;
+}
+
+template <typename T>
+static std::shared_ptr<const T> fromXml(const std::string& content) {
+    std::shared_ptr<T> object = std::make_unique<T>();
+    std::string error;
+    if (fromXml(object.get(), content, &error)) {
+        return object;
+    }
+    LOG(WARNING) << "Unabled to parse: " << error;
+    return nullptr;
+}
+
+static std::shared_ptr<const HalManifest> getDeviceHalManifest(JNIEnv* env) {
+    return fromXml<HalManifest>(runCmd(env, "vintf dm"));
+}
+
+static std::shared_ptr<const HalManifest> getFrameworkHalManifest(JNIEnv* env) {
+    return fromXml<HalManifest>(runCmd(env, "vintf fm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix(JNIEnv* env) {
+    return fromXml<CompatibilityMatrix>(runCmd(env, "vintf dcm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix(JNIEnv* env) {
+    return fromXml<CompatibilityMatrix>(runCmd(env, "vintf fcm"));
+}
+
 template<typename V>
 static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
     size_t i;
@@ -83,12 +135,10 @@
 {
     std::vector<std::string> cStrings;
 
-    tryAddSchema(VintfObject::GetDeviceHalManifest(), "device manifest", &cStrings);
-    tryAddSchema(VintfObject::GetFrameworkHalManifest(), "framework manifest", &cStrings);
-    tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), "device compatibility matrix",
-                 &cStrings);
-    tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), "framework compatibility matrix",
-                 &cStrings);
+    tryAddSchema(getDeviceHalManifest(env), "device manifest", &cStrings);
+    tryAddSchema(getFrameworkHalManifest(env), "framework manifest", &cStrings);
+    tryAddSchema(getDeviceCompatibilityMatrix(env), "device compatibility matrix", &cStrings);
+    tryAddSchema(getFrameworkCompatibilityMatrix(env), "framework compatibility matrix", &cStrings);
 
     return toJavaStringArray(env, cStrings);
 }
@@ -108,15 +158,13 @@
 
 static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
     std::set<std::string> halNames;
-    tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
-            "device manifest", &halNames);
-    tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
-            "framework manifest", &halNames);
+    tryAddHalNamesAndVersions(getDeviceHalManifest(env), "device manifest", &halNames);
+    tryAddHalNamesAndVersions(getFrameworkHalManifest(env), "framework manifest", &halNames);
     return toJavaStringArray(env, halNames);
 }
 
 static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
     if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
         return nullptr;
@@ -126,8 +174,7 @@
 }
 
 static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const CompatibilityMatrix> matrix =
-            VintfObject::GetFrameworkCompatibilityMatrix();
+    std::shared_ptr<const CompatibilityMatrix> matrix = getFrameworkCompatibilityMatrix(env);
     if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
         jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
         return nullptr;
@@ -148,7 +195,7 @@
 }
 
 static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getFrameworkHalManifest(env);
     if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
         LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
         return nullptr;
@@ -163,7 +210,7 @@
 }
 
 static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion(JNIEnv* env, jclass) {
-    std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+    std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
     if (manifest == nullptr || manifest->level() == Level::UNSPECIFIED) {
         return nullptr;
     }
@@ -188,19 +235,20 @@
 
 const char* const kVintfObjectPathName = "android/os/VintfObject";
 
-int register_android_os_VintfObject(JNIEnv* env)
-{
-
+int register_android_os_VintfObject(JNIEnv* env) {
     gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
     gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
     gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
-    gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
-            "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+    gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put",
+                                   "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     gLongClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Long"));
     gLongValueOf = GetStaticMethodIDOrDie(env, gLongClazz, "valueOf", "(J)Ljava/lang/Long;");
+    gVintfObjectClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, kVintfObjectPathName));
+    gRunCommand = GetStaticMethodIDOrDie(env, gVintfObjectClazz, "runShellCommand",
+                                         "(Ljava/lang/String;)Ljava/lang/String;");
 
     return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
-            NELEM(gVintfObjectMethods));
+                                NELEM(gVintfObjectMethods));
 }
 
 extern int register_android_os_VintfRuntimeInfo(JNIEnv* env);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 3ed9f49..dbbcbad 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -116,7 +116,7 @@
 
 using android::zygote::ZygoteFailure;
 
-using Action = android_mallopt_gwp_asan_options_t::Action;
+using Mode = android_mallopt_gwp_asan_options_t::Mode;
 
 // This type is duplicated in fd_utils.h
 typedef const std::function<void(std::string)>& fail_fn_t;
@@ -2101,21 +2101,21 @@
     switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
         default:
         case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT:
-            gwp_asan_options.desire = GetBoolProperty(kGwpAsanAppRecoverableSysprop, true)
-                    ? Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING
-                    : Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+            gwp_asan_options.mode = GetBoolProperty(kGwpAsanAppRecoverableSysprop, true)
+                    ? Mode::APP_MANIFEST_DEFAULT
+                    : Mode::APP_MANIFEST_NEVER;
             android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
             break;
         case RuntimeFlags::GWP_ASAN_LEVEL_NEVER:
-            gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+            gwp_asan_options.mode = Mode::APP_MANIFEST_NEVER;
             android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
             break;
         case RuntimeFlags::GWP_ASAN_LEVEL_ALWAYS:
-            gwp_asan_options.desire = Action::TURN_ON_FOR_APP;
+            gwp_asan_options.mode = Mode::APP_MANIFEST_ALWAYS;
             android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
             break;
         case RuntimeFlags::GWP_ASAN_LEVEL_LOTTERY:
-            gwp_asan_options.desire = Action::TURN_ON_WITH_SAMPLING;
+            gwp_asan_options.mode = Mode::APP_MANIFEST_DEFAULT;
             android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
             break;
     }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7bac338..cf552da 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -178,6 +178,7 @@
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REPLY" />
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
+    <protected-broadcast android:name="android.bluetooth.device.action.KEY_MISSING" />
     <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
     <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.REMOTE_ISSUE_OCCURRED" />
@@ -2257,6 +2258,11 @@
     <permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- @hide Allows access to Thread network APIs or shell commands ("cmd thread_network") which
+        are only for testing. -->
+    <permission android:name="android.permission.THREAD_NETWORK_TESTING"
+                android:protectionLevel="signature" />
+
     <!-- #SystemApi @hide Allows an app to bypass Private DNS.
          <p>Not for use by third-party applications.
          TODO: publish as system API in next API release. -->
diff --git a/core/res/res/drawable/ic_thread_network.xml b/core/res/res/drawable/ic_thread_network.xml
new file mode 100644
index 0000000..1d7608f
--- /dev/null
+++ b/core/res/res/drawable/ic_thread_network.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M476,880Q394,879 322,847.5Q250,816 196,761.5Q142,707 111,634.5Q80,562 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,623 791.5,732.5Q703,842 563,871L563,480L607,480Q661,480 699.5,441.5Q738,403 738,349Q738,295 699.5,256.5Q661,218 607,218Q553,218 514.5,256.5Q476,295 476,349L476,393L345,393Q279,393 233,439Q187,485 187,551Q187,617 233,662.5Q279,708 345,708L345,621Q316,621 295,600.5Q274,580 274,551Q274,522 295,501Q316,480 345,480L476,480L476,880ZM563,393L563,349Q563,331 576,318Q589,305 607,305Q625,305 638,318Q651,331 651,349Q651,367 638,380Q625,393 607,393L563,393Z"/>
+</vector>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fd6158d..7bd74c8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1367,6 +1367,7 @@
   <java-symbol type="drawable" name="platlogo" />
   <java-symbol type="drawable" name="stat_notify_sync_error" />
   <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
+  <java-symbol type="drawable" name="ic_thread_network" />
   <java-symbol type="drawable" name="ic_wifi_signal_0" />
   <java-symbol type="drawable" name="ic_wifi_signal_1" />
   <java-symbol type="drawable" name="ic_wifi_signal_2" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 4d7c009..67cceb5 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -60,6 +60,9 @@
     <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
     <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
 
+    <!-- Burkina Faso: 1-4 digits (standard system default, not country specific) -->
+    <shortcode country="bf" pattern="\\d{1,4}" free="3558" />
+
     <!-- Bulgaria: 4-5 digits, plus EU -->
     <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}|1988|1490" />
 
@@ -175,8 +178,8 @@
     <!-- Israel: 1-5 digits, known premium codes listed -->
     <shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" />
 
-    <!-- Iran: 4-6 digits, known premium codes listed -->
-    <shortcode country="ir" pattern="\\d{4,6}" free="700791|700792" />
+    <!-- Iran: 4-8 digits, known premium codes listed -->
+    <shortcode country="ir" pattern="\\d{4,8}" free="700791|700792|100016|30008360" />
 
     <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU:
          https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
@@ -352,7 +355,7 @@
     <shortcode country="za" pattern="\\d{1,5}" free="44136|30791|36056|33009" />
 
     <!-- Yemen -->
-    <shortcode country="ye" pattern="\\d{1,4}" free="5081" />
+    <shortcode country="ye" pattern="\\d{1,4}" free="5079" />
 
     <!-- Zimbabwe -->
     <shortcode country="zw" pattern="\\d{1,5}" free="33679" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 871feb6..5a051ad 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -103,6 +103,7 @@
     sdk_version: "core_platform",
     test_suites: [
         "device-tests",
+        "device-platinum-tests",
         "automotive-tests",
     ],
 
@@ -211,6 +212,8 @@
         "src/com/android/internal/util/**/*.java",
         "src/com/android/internal/power/EnergyConsumerStatsTest.java",
         ":FrameworksCoreTests{.aapt.srcjar}",
+        "src/com/android/internal/ravenwood/**/*.java",
+
         ":FrameworksCoreTests-aidl",
         ":FrameworksCoreTests-helpers",
         ":FrameworksCoreTestDoubles-sources",
diff --git a/core/tests/coretests/src/android/net/OWNERS b/core/tests/coretests/src/android/net/OWNERS
index a779c00..beb77dc 100644
--- a/core/tests/coretests/src/android/net/OWNERS
+++ b/core/tests/coretests/src/android/net/OWNERS
@@ -1,4 +1,5 @@
 include /services/core/java/com/android/server/net/OWNERS
 
-per-file SSL*,Uri*,Url* = prb@google.com,oth@google.com,narayan@google.com,ngeoffray@google.com
+per-file SSL*,Url* = prb@google.com,oth@google.com,narayan@google.com,ngeoffray@google.com
 per-file SntpClient* = file:/services/core/java/com/android/server/timedetector/OWNERS
+per-file Uri* = varunshah@google.com
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index f34b8fd..f81b31d 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -16,16 +16,25 @@
 
 package android.os;
 
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.stream.Collectors.toList;
 
 import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
+import android.util.Pair;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.util.stream.Stream;
+
+import javax.xml.parsers.DocumentBuilderFactory;
 
 @RunWith(AndroidJUnit4.class)
 @IgnoreUnderRavenwood(blockedBy = VintfObject.class)
@@ -39,12 +48,26 @@
     @Test
     public void testReport() {
         String[] xmls = VintfObject.report();
-        assertTrue(xmls.length > 0);
-        // From /system/manifest.xml
-        assertTrue(String.join("", xmls).contains(
-                "<manifest version=\"1.0\" type=\"framework\">"));
-        // From /system/compatibility-matrix.xml
-        assertTrue(String.join("", xmls).contains(
-                "<compatibility-matrix version=\"1.0\" type=\"framework\""));
+
+        assertThat(Stream.of(xmls).map(xml -> rootAndType(xml)).collect(toList()))
+                .containsExactly(
+                    Pair.create("manifest", "framework"),
+                    Pair.create("compatibility-matrix", "framework"),
+                    Pair.create("manifest", "device"),
+                    Pair.create("compatibility-matrix", "device")
+                );
+    }
+
+    private static Pair<String, String> rootAndType(String content) {
+        try {
+            var factory = DocumentBuilderFactory.newInstance();
+            var builder = factory.newDocumentBuilder();
+            var inputSource = new InputSource(new StringReader(content));
+            var document = builder.parse(inputSource);
+            var root = document.getDocumentElement();
+            return Pair.create(root.getTagName(), root.getAttribute("type"));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java
new file mode 100644
index 0000000..4eccbe5
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.content.res;
+
+import static com.android.internal.content.om.OverlayConfigParser.SysPropWrapper;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.content.om.OverlayConfigParser;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class OverlayConfigParserTest {
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropNotRoProp() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${persist.value}/path", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropMissingEndBracket() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${ro.value/path", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergeOnlyPropStart() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("path/${", sysProp);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropInProp() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("path/${${ro.value}}", sysProp);
+    }
+
+    /**
+     * The path is only allowed to contain one property.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testMergePropMultipleProps() {
+        SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+        OverlayConfigParser.expandProperty("${ro.value}/path${ro.value2}/path", sysProp);
+    }
+
+    @Test
+    public void testMergePropOneProp() {
+        final SysPropWrapper sysProp = p -> {
+            if ("ro.value".equals(p)) {
+                return "dummy_value";
+            } else {
+                return "invalid";
+            }
+        };
+
+        // Property in the beginnig of the string
+        String result = OverlayConfigParser.expandProperty("${ro.value}/path",
+                sysProp);
+        assertEquals("dummy_value/path", result);
+
+        // Property in the middle of the string
+        result = OverlayConfigParser.expandProperty("path/${ro.value}/file",
+                sysProp);
+        assertEquals("path/dummy_value/file", result);
+
+        // Property at the of the string
+        result = OverlayConfigParser.expandProperty("path/${ro.value}",
+                sysProp);
+        assertEquals("path/dummy_value", result);
+
+        // Property is the entire string
+        result = OverlayConfigParser.expandProperty("${ro.value}",
+                sysProp);
+        assertEquals("dummy_value", result);
+    }
+
+    @Test
+    public void testMergePropNoProp() {
+        final SysPropWrapper sysProp = p -> {
+            return "dummy_value";
+        };
+
+        final String path = "no_props/path";
+        String result = OverlayConfigParser.expandProperty(path, sysProp);
+        assertEquals(path, result);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
new file mode 100644
index 0000000..d1ef61b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.ravenwood;
+
+import static junit.framework.TestCase.assertEquals;
+
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RavenwoodEnvironmentTest {
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+    @Test
+    public void testIsRunningOnRavenwood() {
+        assertEquals(RavenwoodRule.isUnderRavenwood(),
+                RavenwoodEnvironment.getInstance().isRunningOnRavenwood());
+    }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
index 4c00c16..9785ca7 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
@@ -216,6 +216,46 @@
     }
 
     @Test
+    public void testBufferSizeWithConsecutiveDelimiters() throws Exception {
+        // Read numbers using very small buffer size, exercising fillBuf()
+        // Include more consecutive delimiters than the buffer size.
+        final ProcFileReader reader =
+                buildReader("1   21  3  41           5  61  7  81 9   10\n", 3);
+
+        assertEquals(1, reader.nextInt());
+        assertEquals(21, reader.nextInt());
+        assertEquals(3, reader.nextInt());
+        assertEquals(41, reader.nextInt());
+        assertEquals(5, reader.nextInt());
+        assertEquals(61, reader.nextInt());
+        assertEquals(7, reader.nextInt());
+        assertEquals(81, reader.nextInt());
+        assertEquals(9, reader.nextInt());
+        assertEquals(10, reader.nextInt());
+        reader.finishLine();
+        assertFalse(reader.hasMoreData());
+    }
+
+    @Test
+    public void testBufferSizeWithConsecutiveDelimitersAndMultipleLines() throws Exception {
+        final ProcFileReader reader =
+                buildReader("1 21  41    \n    5  7     81   \n    9 10     \n", 3);
+
+        assertEquals(1, reader.nextInt());
+        assertEquals(21, reader.nextInt());
+        assertEquals(41, reader.nextInt());
+        reader.finishLine();
+        assertEquals(5, reader.nextInt());
+        assertEquals(7, reader.nextInt());
+        assertEquals(81, reader.nextInt());
+        reader.finishLine();
+        assertEquals(9, reader.nextInt());
+        assertEquals(10, reader.nextInt());
+        reader.finishLine();
+        assertFalse(reader.hasMoreData());
+    }
+
+    @Test
     public void testIgnore() throws Exception {
         final ProcFileReader reader = buildReader("a b c\n");
 
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index cb803f7..5045918 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -322,11 +322,11 @@
     <library name="android.hidl.manager-V1.0-java"
             file="/system/framework/android.hidl.manager-V1.0-java.jar" />
 
-    <!-- These are the standard packages that are white-listed to always have internet
+    <!-- These are the standard packages that are allowed to always have internet
          access while in power save mode, even if they aren't in the foreground. -->
     <allow-in-power-save package="com.android.providers.downloads" />
 
-    <!-- These are the standard packages that are white-listed to always have internet
+    <!-- These are the standard packages that are allowed to always have internet
          access while in data mode, even if they aren't in the foreground. -->
     <allow-in-data-usage-save package="com.android.providers.downloads" />
 
@@ -338,7 +338,7 @@
     <!-- Emergency app needs to run in the background to reliably provide safety features -->
     <allow-in-power-save package="com.android.emergency" />
 
-    <!-- Whitelist system providers -->
+    <!-- Allow system providers -->
     <!-- Calendar provider needs alarms while in idle -->
     <allow-in-power-save package="com.android.providers.calendar" />
     <allow-in-power-save-except-idle package="com.android.providers.contacts" />
diff --git a/data/keyboards/Android.bp b/data/keyboards/Android.bp
index f15c153..423b55b 100644
--- a/data/keyboards/Android.bp
+++ b/data/keyboards/Android.bp
@@ -27,3 +27,27 @@
         targets: ["droidcore"],
     },
 }
+
+prebuilt_usr_keylayout {
+    name: "keylayout_data",
+    srcs: [
+        "*.kl",
+    ],
+    no_full_install: true,
+}
+
+prebuilt_usr_keychars {
+    name: "keychars_data",
+    srcs: [
+        "*.kcm",
+    ],
+    no_full_install: true,
+}
+
+prebuilt_usr_idc {
+    name: "idc_data",
+    srcs: [
+        "*.idc",
+    ],
+    no_full_install: true,
+}
diff --git a/graphics/java/Android.bp b/graphics/java/Android.bp
index db37a387..0937f14 100644
--- a/graphics/java/Android.bp
+++ b/graphics/java/Android.bp
@@ -10,6 +10,7 @@
 aconfig_declarations {
     name: "framework_graphics_flags",
     package: "com.android.graphics.flags",
+    container: "system",
     srcs: ["android/framework_graphics.aconfig"],
 }
 
diff --git a/graphics/java/android/framework_graphics.aconfig b/graphics/java/android/framework_graphics.aconfig
index 6c81a60..f13f369 100644
--- a/graphics/java/android/framework_graphics.aconfig
+++ b/graphics/java/android/framework_graphics.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.graphics.flags"
+container: "system"
 
 flag {
      name: "exact_compute_bounds"
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index d915b74..1c20141 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -143,7 +143,7 @@
          * the decoder will try to pick the best matching config based on the
          * system's screen depth, and characteristics of the original image such
          * as if it has per-pixel alpha (requiring a config that also does).
-         * 
+         *
          * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by
          * default.
          */
@@ -183,7 +183,7 @@
 
         /**
          * If true (which is the default), the resulting bitmap will have its
-         * color channels pre-multipled by the alpha channel.
+         * color channels pre-multiplied by the alpha channel.
          *
          * <p>This should NOT be set to false for images to be directly drawn by
          * the view system or through a {@link Canvas}. The view system and
@@ -221,9 +221,9 @@
          * if {@link #inScaled} is set (which it is by default} and this
          * density does not match {@link #inTargetDensity}, then the bitmap
          * will be scaled to the target density before being returned.
-         * 
+         *
          * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)}, 
+         * {@link BitmapFactory#decodeResource(Resources, int)},
          * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
          * and {@link BitmapFactory#decodeResourceStream}
          * will fill in the density associated with the resource.  The other
@@ -242,29 +242,29 @@
          * This is used in conjunction with {@link #inDensity} and
          * {@link #inScaled} to determine if and how to scale the bitmap before
          * returning it.
-         * 
+         *
          * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)}, 
+         * {@link BitmapFactory#decodeResource(Resources, int)},
          * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
          * and {@link BitmapFactory#decodeResourceStream}
          * will fill in the density associated the Resources object's
          * DisplayMetrics.  The other
          * functions will leave it as-is and no scaling for density will be
          * performed.
-         * 
+         *
          * @see #inDensity
          * @see #inScreenDensity
          * @see #inScaled
          * @see android.util.DisplayMetrics#densityDpi
          */
         public int inTargetDensity;
-        
+
         /**
          * The pixel density of the actual screen that is being used.  This is
          * purely for applications running in density compatibility code, where
          * {@link #inTargetDensity} is actually the density the application
          * sees rather than the real screen density.
-         * 
+         *
          * <p>By setting this, you
          * allow the loading code to avoid scaling a bitmap that is currently
          * in the screen density up/down to the compatibility density.  Instead,
@@ -274,18 +274,18 @@
          * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
          * Bitmap.getScaledHeight} to account for any different between the
          * bitmap's density and the target's density.
-         * 
+         *
          * <p>This is never set automatically for the caller by
          * {@link BitmapFactory} itself.  It must be explicitly set, since the
          * caller must deal with the resulting bitmap in a density-aware way.
-         * 
+         *
          * @see #inDensity
          * @see #inTargetDensity
          * @see #inScaled
          * @see android.util.DisplayMetrics#densityDpi
          */
         public int inScreenDensity;
-        
+
         /**
          * When this flag is set, if {@link #inDensity} and
          * {@link #inTargetDensity} are not 0, the
@@ -345,7 +345,7 @@
          * ignored.
          *
          * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, this
-         * field works in conjuction with inPurgeable. If inPurgeable is false,
+         * field works in conjunction with inPurgeable. If inPurgeable is false,
          * then this field is ignored. If inPurgeable is true, then this field
          * determines whether the bitmap can share a reference to the input
          * data (inputstream, array, etc.) or if it must make a deep copy.
@@ -583,11 +583,11 @@
                 opts.inDensity = density;
             }
         }
-        
+
         if (opts.inTargetDensity == 0 && res != null) {
             opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
         }
-        
+
         return decodeStream(is, pad, opts);
     }
 
@@ -611,8 +611,8 @@
     public static Bitmap decodeResource(Resources res, int id, Options opts) {
         validate(opts);
         Bitmap bm = null;
-        InputStream is = null; 
-        
+        InputStream is = null;
+
         try {
             final TypedValue value = new TypedValue();
             is = res.openRawResource(id, value);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d1aceaf..5291f7b 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -52,7 +52,7 @@
  * Canvas and Drawables</a> developer guide.</p></div>
  */
 public class Canvas extends BaseCanvas {
-    private static int sCompatiblityVersion = 0;
+    private static int sCompatibilityVersion = 0;
     private static boolean sCompatibilityRestore = false;
     private static boolean sCompatibilitySetBitmap = false;
 
@@ -71,7 +71,7 @@
 
     // Maximum bitmap size as defined in Skia's native code
     // (see SkCanvas.cpp, SkDraw.cpp)
-    private static final int MAXMIMUM_BITMAP_SIZE = 32766;
+    private static final int MAXIMUM_BITMAP_SIZE = 32766;
 
     // Use a Holder to allow static initialization of Canvas in the boot image.
     private static class NoImagePreloadHolder {
@@ -316,7 +316,7 @@
      * @see #getMaximumBitmapHeight()
      */
     public int getMaximumBitmapWidth() {
-        return MAXMIMUM_BITMAP_SIZE;
+        return MAXIMUM_BITMAP_SIZE;
     }
 
     /**
@@ -327,7 +327,7 @@
      * @see #getMaximumBitmapWidth()
      */
     public int getMaximumBitmapHeight() {
-        return MAXMIMUM_BITMAP_SIZE;
+        return MAXIMUM_BITMAP_SIZE;
     }
 
     // the SAVE_FLAG constants must match their native equivalents
@@ -408,7 +408,7 @@
     public static final int ALL_SAVE_FLAG = 0x1F;
 
     private static void checkValidSaveFlags(int saveFlags) {
-        if (sCompatiblityVersion >= Build.VERSION_CODES.P
+        if (sCompatibilityVersion >= Build.VERSION_CODES.P
                 && saveFlags != ALL_SAVE_FLAG) {
             throw new IllegalArgumentException(
                     "Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed");
@@ -817,7 +817,7 @@
     }
 
     private static void checkValidClipOp(@NonNull Region.Op op) {
-        if (sCompatiblityVersion >= Build.VERSION_CODES.P
+        if (sCompatibilityVersion >= Build.VERSION_CODES.P
                 && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {
             throw new IllegalArgumentException(
                     "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");
@@ -1383,7 +1383,7 @@
     }
 
     /*package*/ static void setCompatibilityVersion(int apiLevel) {
-        sCompatiblityVersion = apiLevel;
+        sCompatibilityVersion = apiLevel;
         sCompatibilityRestore = apiLevel < Build.VERSION_CODES.M;
         sCompatibilitySetBitmap = apiLevel < Build.VERSION_CODES.O;
         nSetCompatibilityVersion(apiLevel);
diff --git a/graphics/java/android/graphics/ComposePathEffect.java b/graphics/java/android/graphics/ComposePathEffect.java
index 3fc9eb5..7d59ece 100644
--- a/graphics/java/android/graphics/ComposePathEffect.java
+++ b/graphics/java/android/graphics/ComposePathEffect.java
@@ -20,13 +20,13 @@
 
     /**
      * Construct a PathEffect whose effect is to apply first the inner effect
-     * and the the outer pathEffect (e.g. outer(inner(path))).
+     * and the outer pathEffect (e.g. outer(inner(path))).
      */
     public ComposePathEffect(PathEffect outerpe, PathEffect innerpe) {
         native_instance = nativeCreate(outerpe.native_instance,
                                        innerpe.native_instance);
     }
-    
+
     private static native long nativeCreate(long nativeOuterpe,
                                             long nativeInnerpe);
 }
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index f50de16..91fa1a6 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -215,7 +215,7 @@
 
     @CriticalNative
     private static native long nGetFamilyReleaseFunc();
-    // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font.
+    // By passing -1 to weight argument, the weight value is resolved by OS/2 table in the font.
     // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font.
     private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
             int weight, int isItalic);
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 52b0b95..2d3ffb5 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -127,7 +127,7 @@
             parser.setInput(is, null);
             parser.nextTag();
             return readFamilies(parser, systemFontDir, oemCustomization, updatableFontMap,
-                    lastModifiedDate, configVersion, false /* filter out the non-exising files */);
+                    lastModifiedDate, configVersion, false /* filter out the non-existing files */);
         }
     }
 
@@ -254,7 +254,7 @@
      * @param parser An XML parser.
      * @param fontDir a font directory name.
      * @param updatableFontMap a updated font file map.
-     * @param allowNonExistingFile true to allow font file that doesn't exists
+     * @param allowNonExistingFile true to allow font file that doesn't exist.
      * @return a FontFamily instance. null if no font files are available in this FontFamily.
      */
     public static @Nullable FontConfig.FontFamily readFamily(XmlPullParser parser, String fontDir,
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index b3615ff..8f12828 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -24,7 +24,7 @@
 /**
  * Class that contains all the timing information for the current frame. This
  * is used in conjunction with the hardware renderer to provide
- * continous-monitoring jank events
+ * continuous-monitoring jank events
  *
  * All times in nanoseconds from CLOCK_MONOTONIC/System.nanoTime()
  *
diff --git a/graphics/java/android/graphics/Interpolator.java b/graphics/java/android/graphics/Interpolator.java
index 1045464..418922f7 100644
--- a/graphics/java/android/graphics/Interpolator.java
+++ b/graphics/java/android/graphics/Interpolator.java
@@ -25,13 +25,13 @@
         mFrameCount = 2;
         native_instance = nativeConstructor(valueCount, 2);
     }
-    
+
     public Interpolator(int valueCount, int frameCount) {
         mValueCount = valueCount;
         mFrameCount = frameCount;
         native_instance = nativeConstructor(valueCount, frameCount);
     }
-    
+
     /**
      * Reset the Interpolator to have the specified number of values and an
      * implicit keyFrame count of 2 (just a start and end). After this call the
@@ -40,7 +40,7 @@
     public void reset(int valueCount) {
         reset(valueCount, 2);
     }
-    
+
     /**
      * Reset the Interpolator to have the specified number of values and
      * keyFrames. After this call the values for each keyFrame must be assigned
@@ -51,20 +51,20 @@
         mFrameCount = frameCount;
         nativeReset(native_instance, valueCount, frameCount);
     }
-    
+
     public final int getKeyFrameCount() {
         return mFrameCount;
     }
-    
+
     public final int getValueCount() {
         return mValueCount;
     }
-    
+
     /**
      * Assign the keyFrame (specified by index) a time value and an array of key
-     * values (with an implicity blend array of [0, 0, 1, 1] giving linear
+     * values (with an implicitly blend array of [0, 0, 1, 1] giving linear
      * transition to the next set of key values).
-     * 
+     *
      * @param index The index of the key frame to assign
      * @param msec The time (in mililiseconds) for this key frame. Based on the
      *        SystemClock.uptimeMillis() clock
@@ -77,7 +77,7 @@
     /**
      * Assign the keyFrame (specified by index) a time value and an array of key
      * values and blend array.
-     * 
+     *
      * @param index The index of the key frame to assign
      * @param msec The time (in mililiseconds) for this key frame. Based on the
      *        SystemClock.uptimeMillis() clock
@@ -96,7 +96,7 @@
         }
         nativeSetKeyFrame(native_instance, index, msec, values, blend);
     }
-    
+
     /**
      * Set a repeat count (which may be fractional) for the interpolator, and
      * whether the interpolator should mirror its repeats. The default settings
@@ -107,7 +107,7 @@
             nativeSetRepeatMirror(native_instance, repeatCount, mirror);
         }
     }
-    
+
     public enum Result {
         NORMAL,
         FREEZE_START,
@@ -127,7 +127,7 @@
      * return whether the specified time was within the range of key times
      * (NORMAL), was before the first key time (FREEZE_START) or after the last
      * key time (FREEZE_END). In any event, computed values are always returned.
-     * 
+     *
      * @param msec The time (in milliseconds) used to sample into the
      *        Interpolator. Based on the SystemClock.uptimeMillis() clock
      * @param values Where to write the computed values (may be NULL).
@@ -143,13 +143,13 @@
             default: return Result.FREEZE_END;
         }
     }
-    
+
     @Override
     protected void finalize() throws Throwable {
         nativeDestructor(native_instance);
         native_instance = 0;  // Other finalizers can still call us.
     }
-    
+
     private int mValueCount;
     private int mFrameCount;
     private long native_instance;
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index 0aa6f12..fe73a1a 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkColorFilter.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 56d912b..0879371 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -63,7 +63,7 @@
      * @param colors       The sRGB colors to be distributed along the gradient line
      * @param positions    May be null. The relative positions [0..1] of
      *                     each corresponding color in the colors array. If this is null,
-     *                     the the colors are distributed evenly along the gradient line.
+     *                     the colors are distributed evenly along the gradient line.
      * @param tile         The Shader tiling mode
      */
     public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors,
@@ -82,7 +82,7 @@
      * @param colors       The colors to be distributed along the gradient line
      * @param positions    May be null. The relative positions [0..1] of
      *                     each corresponding color in the colors array. If this is null,
-     *                     the the colors are distributed evenly along the gradient line.
+     *                     the colors are distributed evenly along the gradient line.
      * @param tile         The Shader tiling mode
      *
      * @throws IllegalArgumentException if there are less than two colors, the colors do
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index bc58feb..66553d8 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -559,7 +559,7 @@
 
     /**
      * Set the matrix to the scale and translate values that map the source rectangle to the
-     * destination rectangle, returning true if the the result can be represented.
+     * destination rectangle, returning true if the result can be represented.
      *
      * @param src the source rectangle to map from.
      * @param dst the destination rectangle to map to.
diff --git a/graphics/java/android/graphics/Mesh.java b/graphics/java/android/graphics/Mesh.java
index a4bce9e..6be8332 100644
--- a/graphics/java/android/graphics/Mesh.java
+++ b/graphics/java/android/graphics/Mesh.java
@@ -271,7 +271,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than int
      * or int[1] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value       value corresponding to the int uniform with the given name.
      */
     public void setIntUniform(@NonNull String uniformName, int value) {
@@ -283,7 +283,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec2
      * or int[2] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      */
@@ -296,7 +296,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec3
      * or int[3] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      * @param value3      third value corresponding to the int uniform with the given name.
@@ -310,7 +310,7 @@
      * not have a uniform with that name or if the uniform is declared with a type other than ivec4
      * or int[4] then an IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param value1      first value corresponding to the int uniform with the given name.
      * @param value2      second value corresponding to the int uniform with the given name.
      * @param value3      third value corresponding to the int uniform with the given name.
@@ -327,7 +327,7 @@
      * int (for N=1), ivecN, or int[N], where N is the length of the values param, then an
      * IllegalArgumentException is thrown.
      *
-     * @param uniformName name matching the int uniform delcared in the shader program.
+     * @param uniformName name matching the int uniform declared in the shader program.
      * @param values      int values corresponding to the vec4 int uniform with the given name.
      */
     public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) {
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index af20957..382269f 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -22,12 +22,12 @@
  * The NinePatch class permits drawing a bitmap in nine or more sections.
  * Essentially, it allows the creation of custom graphics that will scale the
  * way that you define, when content added within the image exceeds the normal
- * bounds of the graphic. For a thorough explanation of a NinePatch image, 
- * read the discussion in the 
+ * bounds of the graphic. For a thorough explanation of a NinePatch image,
+ * read the discussion in the
  * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D
  * Graphics</a> document.
  * <p>
- * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> 
+ * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a>
  * tool offers an extremely handy way to create your NinePatch images,
  * using a WYSIWYG graphics editor.
  * </p>
@@ -104,7 +104,7 @@
         this(bitmap, chunk, null);
     }
 
-    /** 
+    /**
      * Create a drawable projection from a bitmap to nine patches.
      *
      * @param bitmap The bitmap describing the patches.
@@ -122,7 +122,7 @@
     protected void finalize() throws Throwable {
         try {
             if (mNativeChunk != 0) {
-                // only attempt to destroy correctly initilized chunks
+                // only attempt to destroy correctly initialized chunks
                 nativeFinalize(mNativeChunk);
                 mNativeChunk = 0;
             }
@@ -169,8 +169,8 @@
     public Bitmap getBitmap() {
         return mBitmap;
     }
-    
-    /** 
+
+    /**
      * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
      * @param canvas A container for the current matrix and clip used to draw the NinePatch.
@@ -180,7 +180,7 @@
         canvas.drawPatch(this, location, mPaint);
     }
 
-    /** 
+    /**
      * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
      * @param canvas A container for the current matrix and clip used to draw the NinePatch.
@@ -190,7 +190,7 @@
         canvas.drawPatch(this, location, mPaint);
     }
 
-    /** 
+    /**
      * Draws the NinePatch. This method will ignore the paint returned
      * by {@link #getPaint()} and use the specified paint instead.
      *
diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java
index 5500c52..2c6cfa5 100644
--- a/graphics/java/android/graphics/PathMeasure.java
+++ b/graphics/java/android/graphics/PathMeasure.java
@@ -25,14 +25,14 @@
      * setPath.
      *
      * Note that once a path is associated with the measure object, it is
-     * undefined if the path is subsequently modified and the the measure object
+     * undefined if the path is subsequently modified and the measure object
      * is used. If the path is modified, you must call setPath with the path.
      */
     public PathMeasure() {
         mPath = null;
         native_instance = native_create(0, false);
     }
-    
+
     /**
      * Create a PathMeasure object associated with the specified path object
      * (already created and specified). The measure object can now return the
@@ -40,7 +40,7 @@
      * path.
      *
      * Note that once a path is associated with the measure object, it is
-     * undefined if the path is subsequently modified and the the measure object
+     * undefined if the path is subsequently modified and the measure object
      * is used. If the path is modified, you must call setPath with the path.
      *
      * @param path The path that will be measured by this object
@@ -121,7 +121,7 @@
      * such as <code>dst.rLineTo(0, 0)</code>.</p>
      */
     public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) {
-        // Skia used to enforce this as part of it's API, but has since relaxed that restriction
+        // Skia used to enforce this as part of its API, but has since relaxed that restriction
         // so to maintain consistency in our API we enforce the preconditions here.
         float length = getLength();
         if (startD < 0) {
diff --git a/graphics/java/android/graphics/Rasterizer.java b/graphics/java/android/graphics/Rasterizer.java
index 29d82fa..5750954 100644
--- a/graphics/java/android/graphics/Rasterizer.java
+++ b/graphics/java/android/graphics/Rasterizer.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkRasterizer.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 411a10b..5211e3a 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -165,7 +165,7 @@
     public String toShortString() {
         return toShortString(new StringBuilder(32));
     }
-    
+
     /**
      * Return a string representation of the rectangle in a compact form.
      * @hide
@@ -184,7 +184,7 @@
      *
      * <p>You can later recover the Rect from this string through
      * {@link #unflattenFromString(String)}.
-     * 
+     *
      * @return Returns a new String of the form "left top right bottom"
      */
     @NonNull
@@ -314,7 +314,7 @@
     public final int height() {
         return bottom - top;
     }
-    
+
     /**
      * @return the horizontal center of the rectangle. If the computed value
      *         is fractional, this method returns the largest integer that is
@@ -323,7 +323,7 @@
     public final int centerX() {
         return (left + right) >> 1;
     }
-    
+
     /**
      * @return the vertical center of the rectangle. If the computed value
      *         is fractional, this method returns the largest integer that is
@@ -332,14 +332,14 @@
     public final int centerY() {
         return (top + bottom) >> 1;
     }
-    
+
     /**
      * @return the exact horizontal center of the rectangle as a float.
      */
     public final float exactCenterX() {
         return (left + right) * 0.5f;
     }
-    
+
     /**
      * @return the exact vertical center of the rectangle as a float.
      */
@@ -493,7 +493,7 @@
      * @param top The top of the rectangle being tested for containment
      * @param right The right side of the rectangle being tested for containment
      * @param bottom The bottom of the rectangle being tested for containment
-     * @return true iff the the 4 specified sides of a rectangle are inside or
+     * @return true iff the 4 specified sides of a rectangle are inside or
      *              equal to this rectangle
      */
     public boolean contains(int left, int top, int right, int bottom) {
@@ -548,7 +548,7 @@
         }
         return false;
     }
-    
+
     /**
      * If the specified rectangle intersects this rectangle, return true and set
      * this rectangle to that intersection, otherwise return false and do not
@@ -670,7 +670,7 @@
     public void union(@NonNull Rect r) {
         union(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * Update this Rect to enclose itself and the [x,y] coordinate. There is no
      * check to see that this rectangle is non-empty.
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index ff50a0c..5b9b764 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -38,7 +38,7 @@
     public float top;
     public float right;
     public float bottom;
-    
+
     /**
      * Create a new empty RectF. All coordinates are initialized to 0.
      */
@@ -78,7 +78,7 @@
             bottom = r.bottom;
         }
     }
-    
+
     public RectF(@Nullable Rect r) {
         if (r == null) {
             left = top = right = bottom = 0.0f;
@@ -121,7 +121,7 @@
     public String toShortString() {
         return toShortString(new StringBuilder(32));
     }
-    
+
     /**
      * Return a string representation of the rectangle in a compact form.
      * @hide
@@ -134,7 +134,7 @@
         sb.append(','); sb.append(bottom); sb.append(']');
         return sb.toString();
     }
-    
+
     /**
      * Print short representation to given writer.
      * @hide
@@ -183,14 +183,14 @@
     public final float centerY() {
         return (top + bottom) * 0.5f;
     }
-    
+
     /**
      * Set the rectangle to (0,0,0,0)
      */
     public void setEmpty() {
         left = right = top = bottom = 0;
     }
-    
+
     /**
      * Set the rectangle's coordinates to the specified values. Note: no range
      * checking is performed, so it is up to the caller to ensure that
@@ -220,7 +220,7 @@
         this.right  = src.right;
         this.bottom = src.bottom;
     }
-    
+
     /**
      * Copy the coordinates from src into this rectangle.
      *
@@ -261,7 +261,7 @@
         left = newLeft;
         top = newTop;
     }
-    
+
     /**
      * Inset the rectangle by (dx,dy). If dx is positive, then the sides are
      * moved inwards, making the rectangle narrower. If dx is negative, then the
@@ -293,7 +293,7 @@
         return left < right && top < bottom  // check for empty first
                 && x >= left && x < right && y >= top && y < bottom;
     }
-    
+
     /**
      * Returns true iff the 4 specified sides of a rectangle are inside or equal
      * to this rectangle. i.e. is this rectangle a superset of the specified
@@ -303,7 +303,7 @@
      * @param top The top of the rectangle being tested for containment
      * @param right The right side of the rectangle being tested for containment
      * @param bottom The bottom of the rectangle being tested for containment
-     * @return true iff the the 4 specified sides of a rectangle are inside or
+     * @return true iff the 4 specified sides of a rectangle are inside or
      *              equal to this rectangle
      */
     public boolean contains(float left, float top, float right, float bottom) {
@@ -313,7 +313,7 @@
                 && this.left <= left && this.top <= top
                 && this.right >= right && this.bottom >= bottom;
     }
-    
+
     /**
      * Returns true iff the specified rectangle r is inside or equal to this
      * rectangle. An empty rectangle never contains another rectangle.
@@ -329,7 +329,7 @@
                 && left <= r.left && top <= r.top
                 && right >= r.right && bottom >= r.bottom;
     }
-    
+
     /**
      * If the rectangle specified by left,top,right,bottom intersects this
      * rectangle, return true and set this rectangle to that intersection,
@@ -367,7 +367,7 @@
         }
         return false;
     }
-    
+
     /**
      * If the specified rectangle intersects this rectangle, return true and set
      * this rectangle to that intersection, otherwise return false and do not
@@ -382,7 +382,7 @@
     public boolean intersect(@NonNull RectF r) {
         return intersect(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * If rectangles a and b intersect, return true and set this rectangle to
      * that intersection, otherwise return false and do not change this
@@ -406,7 +406,7 @@
         }
         return false;
     }
-    
+
     /**
      * Returns true if this rectangle intersects the specified rectangle.
      * In no event is this rectangle modified. No check is performed to see
@@ -426,7 +426,7 @@
         return this.left < right && left < this.right
                 && this.top < bottom && top < this.bottom;
     }
-    
+
     /**
      * Returns true iff the two specified rectangles intersect. In no event are
      * either of the rectangles modified. To record the intersection,
@@ -441,7 +441,7 @@
         return a.left < b.right && b.left < a.right
                 && a.top < b.bottom && b.top < a.bottom;
     }
-    
+
     /**
      * Set the dst integer Rect by rounding this rectangle's coordinates
      * to their nearest integer values.
@@ -489,7 +489,7 @@
             }
         }
     }
-    
+
     /**
      * Update this Rect to enclose itself and the specified rectangle. If the
      * specified rectangle is empty, nothing is done. If this rectangle is empty
@@ -500,7 +500,7 @@
     public void union(@NonNull RectF r) {
         union(r.left, r.top, r.right, r.bottom);
     }
-    
+
     /**
      * Update this Rect to enclose itself and the [x,y] coordinate. There is no
      * check to see that this rectangle is non-empty.
@@ -520,7 +520,7 @@
             bottom = y;
         }
     }
-    
+
     /**
      * Swap top/bottom or left/right if there are flipped (i.e. left > right
      * and/or top > bottom). This can be called if
@@ -548,7 +548,7 @@
     public int describeContents() {
         return 0;
     }
-    
+
     /**
      * Write this rectangle to the specified parcel. To restore a rectangle from
      * a parcel, use readFromParcel()
@@ -561,7 +561,7 @@
         out.writeFloat(right);
         out.writeFloat(bottom);
     }
-    
+
     public static final @android.annotation.NonNull Parcelable.Creator<RectF> CREATOR = new Parcelable.Creator<RectF>() {
         /**
          * Return a new rectangle from the data in the specified parcel.
@@ -572,7 +572,7 @@
             r.readFromParcel(in);
             return r;
         }
-        
+
         /**
          * Return an array of rectangles of the specified size.
          */
@@ -581,7 +581,7 @@
             return new RectF[size];
         }
     };
-    
+
     /**
      * Set the rectangle's coordinates from the data stored in the specified
      * parcel. To write a rectangle to a parcel, call writeToParcel().
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 2732569..0650b78 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -765,12 +765,12 @@
      * Default value is false. See
      * {@link #setProjectBackwards(boolean)} for a description of what this entails.
      *
-     * @param shouldRecieve True if this RenderNode is a projection receiver, false otherwise.
+     * @param shouldReceive True if this RenderNode is a projection receiver, false otherwise.
      *                      Default is false.
      * @return True if the value changed, false if the new value was the same as the previous value.
      */
-    public boolean setProjectionReceiver(boolean shouldRecieve) {
-        return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
+    public boolean setProjectionReceiver(boolean shouldReceive) {
+        return nSetProjectionReceiver(mNativeRenderNode, shouldReceive);
     }
 
     /**
@@ -1799,7 +1799,7 @@
     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
 
     @CriticalNative
-    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
+    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldReceive);
 
     @CriticalNative
     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index dd82fed..c1b531f 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -318,7 +318,7 @@
     }
 
     /**
-     * Releases the the texture content. This is needed in single buffered mode to allow the image
+     * Releases the texture content. This is needed in single buffered mode to allow the image
      * content producer to take ownership of the image buffer.
      * <p>
      * For more information see {@link #SurfaceTexture(int, boolean)}.
@@ -431,7 +431,7 @@
      * error.
      * <p>
      * Note that while calling this method causes all the buffers to be freed
-     * from the perspective of the the SurfaceTexture, if there are additional
+     * from the perspective of the SurfaceTexture, if there are additional
      * references on the buffers (e.g. if a buffer is referenced by a client or
      * by OpenGL ES as a texture) then those buffer will remain allocated.
      * <p>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 4c4e8fa..fd78816 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -600,7 +600,7 @@
          * {@link #setWeight} and {@link #setItalic}.
          *
          * If {@link #setWeight} is not called, the fallback family keeps the default weight.
-         * Similary, if {@link #setItalic} is not called, the fallback family keeps the default
+         * Similarly, if {@link #setItalic} is not called, the fallback family keeps the default
          * italic information. For example, calling {@code builder.setFallback("sans-serif-light")}
          * is equivalent to calling {@code builder.setFallback("sans-serif").setWeight(300)} in
          * terms of fallback. The default weight and italic information are overridden by calling
@@ -794,7 +794,7 @@
         /**
          * Returns the maximum capacity of custom fallback families.
          *
-         * This includes the the first font family passed to the constructor.
+         * This includes the first font family passed to the constructor.
          * It is guaranteed that the value will be greater than or equal to 64.
          *
          * @return the maximum number of font families for the custom fallback
@@ -816,7 +816,7 @@
         /**
          * Sets a system fallback by name.
          *
-         * You can specify generic font familiy names or OEM specific family names. If the system
+         * You can specify generic font family names or OEM specific family names. If the system
          * don't have a specified fallback, the default fallback is used instead.
          * For more information about generic font families, see <a
          * href="https://www.w3.org/TR/css-fonts-4/#generic-font-families">CSS specification</a>
diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java
index 81769e2..6bb22a1 100644
--- a/graphics/java/android/graphics/Xfermode.java
+++ b/graphics/java/android/graphics/Xfermode.java
@@ -16,8 +16,8 @@
 
 // This file was generated from the C++ include file: SkXfermode.h
 // Any changes made to this file will be discarded by the build.
-// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
-// or one of the auxilary file specifications in device/tools/gluemaker.
+// To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
+// or one of the auxiliary file specifications in device/tools/gluemaker.
 
 package android.graphics;
 
@@ -28,7 +28,7 @@
  * Xfermode is the base class for objects that are called to implement custom
  * "transfer-modes" in the drawing pipeline. The static function Create(Modes)
  * can be called to return an instance of any of the predefined subclasses as
- * specified in the Modes enum. When an Xfermode is assigned to an Paint, then
+ * specified in the Modes enum. When an Xfermode is assigned to a Paint, then
  * objects drawn with that paint have the xfermode applied.
  */
 public class Xfermode {
diff --git a/graphics/java/android/graphics/YuvImage.java b/graphics/java/android/graphics/YuvImage.java
index ce35b55..b0c7f20 100644
--- a/graphics/java/android/graphics/YuvImage.java
+++ b/graphics/java/android/graphics/YuvImage.java
@@ -63,7 +63,7 @@
     private int mWidth;
 
     /**
-     * The height of the the image.
+     * The height of the image.
      */
     private int mHeight;
 
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 688425a..7ee7d6b 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -98,7 +98,7 @@
      * extra content to reveal within the clip path when performing affine transformations on the
      * layers.
      *
-     * Each layers will reserve 25% of it's width and height.
+     * Each layers will reserve 25% of its width and height.
      *
      * As a result, the view port of the layers is smaller than their intrinsic width and height.
      */
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 4972e92..7f2feac 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -839,7 +839,7 @@
     }
 
     /**
-     * Describes the current state, as a union of primitve states, such as
+     * Describes the current state, as a union of primitive states, such as
      * {@link android.R.attr#state_focused},
      * {@link android.R.attr#state_selected}, etc.
      * Some drawables may modify their imagery based on the selected state.
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 166a795..29d033e 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -936,7 +936,7 @@
     }
 
     /**
-     * Retrn the inner radius of the ring
+     * Return the inner radius of the ring
      *
      * @see #setInnerRadius(int)
      * @attr ref android.R.styleable#GradientDrawable_innerRadius
diff --git a/graphics/java/android/graphics/drawable/shapes/PathShape.java b/graphics/java/android/graphics/drawable/shapes/PathShape.java
index 393fdee..299f6d5 100644
--- a/graphics/java/android/graphics/drawable/shapes/PathShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/PathShape.java
@@ -93,7 +93,7 @@
             && Float.compare(pathShape.mStdHeight, mStdHeight) == 0
             && Float.compare(pathShape.mScaleX, mScaleX) == 0
             && Float.compare(pathShape.mScaleY, mScaleY) == 0
-            // Path does not have equals implementation but incase it gains one, use it here
+            // Path does not have equals implementation but in case it gains one, use it here
             && Objects.equals(mPath, pathShape.mPath);
     }
 
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 28cc051..9aea246 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -787,7 +787,7 @@
             return false;
         }
 
-        // ByteBuffer#equals compares all bytes which is not performant for e.g HashMap. Since
+        // ByteBuffer#equals compares all bytes which is not performant for e.g. HashMap. Since
         // underlying native font object holds buffer address, check if this buffer points exactly
         // the same address as a shortcut of equality. For being compatible with of API30 or before,
         // check buffer position even if the buffer points the same address.
diff --git a/graphics/java/android/graphics/fonts/FontFileUtil.java b/graphics/java/android/graphics/fonts/FontFileUtil.java
index ff38282..abcafb6 100644
--- a/graphics/java/android/graphics/fonts/FontFileUtil.java
+++ b/graphics/java/android/graphics/fonts/FontFileUtil.java
@@ -34,7 +34,7 @@
  */
 public class FontFileUtil {
 
-    private FontFileUtil() {}  // Do not instanciate
+    private FontFileUtil() {}  // Do not instantiate
 
     /**
      * Unpack the weight value from packed integer.
@@ -87,7 +87,7 @@
         }
 
         if (weight != -1 && italic != -1) {
-            // Both weight/italic style are specifeid by variation settings.
+            // Both weight/italic style are specified by variation settings.
             // No need to look into OS/2 table.
             // TODO: Good to look HVAR table to check if this font supports wght/ital axes.
             return pack(weight, italic == 1);
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 3ef714ed..6e20034 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -151,7 +151,7 @@
                 } else if (defaultFamily != null) {
                     familyListSet.familyList.add(defaultFamily);
                 } else {
-                    // There is no valid for for default fallback. Ignore.
+                    // There is no valid for default fallback. Ignore.
                 }
             }
         }
diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
index 0e3fb16..06ff4c5 100644
--- a/graphics/java/android/graphics/text/LineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -368,8 +368,8 @@
      * @see LineBreaker#computeLineBreaks
      */
     public static class Result {
-        // Following two contstant must be synced with minikin's line breaker.
-        // TODO(nona): Remove these constatns by introducing native methods.
+        // Following two constants must be synced with minikin's line breaker.
+        // TODO(nona): Remove these constants by introducing native methods.
         private static final int TAB_MASK = 0x20000000;
         private static final int HYPHEN_MASK = 0xFF;
         private static final int START_HYPHEN_MASK = 0x18;  // 0b11000
diff --git a/graphics/java/android/graphics/text/PositionedGlyphs.java b/graphics/java/android/graphics/text/PositionedGlyphs.java
index 7932e33..fe20089 100644
--- a/graphics/java/android/graphics/text/PositionedGlyphs.java
+++ b/graphics/java/android/graphics/text/PositionedGlyphs.java
@@ -137,7 +137,7 @@
      * Returns the glyph ID used for drawing the glyph at the given index.
      *
      * @param index the glyph index
-     * @return An glyph ID of the font.
+     * @return A glyph ID of the font.
      */
     @IntRange(from = 0)
     public int getGlyphId(@IntRange(from = 0) int index) {
diff --git a/keystore/java/android/security/AndroidProtectedConfirmation.java b/keystore/java/android/security/AndroidProtectedConfirmation.java
index 268e0a5..dfe485a 100644
--- a/keystore/java/android/security/AndroidProtectedConfirmation.java
+++ b/keystore/java/android/security/AndroidProtectedConfirmation.java
@@ -59,10 +59,6 @@
 
     /**
      * Requests keystore call into the confirmationui HAL to display a prompt.
-     * @deprecated Android Protected Confirmation had a low adoption rate among Android device
-     *             makers and developers alike. Given the lack of devices supporting the
-     *             feature, it is deprecated. Developers can use auth-bound Keystore keys
-     *             as a partial replacement.
      *
      * @param listener the binder to use for callbacks.
      * @param promptText the prompt to display.
@@ -72,7 +68,6 @@
      * @return one of the {@code CONFIRMATIONUI_*} constants, for
      * example {@code KeyStore.CONFIRMATIONUI_OK}.
      */
-    @Deprecated
     public int presentConfirmationPrompt(IConfirmationCallback listener, String promptText,
                                          byte[] extraData, String locale, int uiOptionsAsFlags) {
         try {
@@ -89,16 +84,11 @@
 
     /**
      * Requests keystore call into the confirmationui HAL to cancel displaying a prompt.
-     * @deprecated Android Protected Confirmation had a low adoption rate among Android device
-     *             makers and developers alike. Given the lack of devices supporting the
-     *             feature, it is deprecated. Developers can use auth-bound Keystore keys
-     *             as a partial replacement.
      *
      * @param listener the binder passed to the {@link #presentConfirmationPrompt} method.
      * @return one of the {@code CONFIRMATIONUI_*} constants, for
      * example {@code KeyStore.CONFIRMATIONUI_OK}.
      */
-    @Deprecated
     public int cancelConfirmationPrompt(IConfirmationCallback listener) {
         try {
             getService().cancelPrompt(listener);
@@ -113,14 +103,9 @@
 
     /**
      * Requests keystore to check if the confirmationui HAL is available.
-     * @deprecated Android Protected Confirmation had a low adoption rate among Android device
-     *             makers and developers alike. Given the lack of devices supporting the
-     *             feature, it is deprecated. Developers can use auth-bound Keystore keys
-     *             as a partial replacement.
      *
      * @return whether the confirmationUI HAL is available.
      */
-    @Deprecated
     public boolean isConfirmationPromptSupported() {
         try {
             return getService().isSupported();
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
deleted file mode 100644
index d1d7c14..0000000
--- a/keystore/java/android/security/KeyStore.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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;
-
-/**
- * This class provides some constants and helper methods related to Android's Keystore service.
- * This class was originally much larger, but its functionality was superseded by other classes.
- * It now just contains a few remaining pieces for which the users haven't been updated yet.
- * You may be looking for {@link java.security.KeyStore} instead.
- *
- * @hide
- */
-public class KeyStore {
-
-    // Used for UID field to indicate the calling UID.
-    public static final int UID_SELF = -1;
-}
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 8c42547..7f936f2 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -22,7 +22,6 @@
 import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.os.Process;
-import android.security.KeyStore;
 import android.security.keymaster.KeymasterDefs;
 
 import libcore.util.EmptyArray;
@@ -1008,13 +1007,20 @@
     public static final int NAMESPACE_LOCKSETTINGS = 103;
 
     /**
+     * The legacy UID that corresponds to {@link #NAMESPACE_APPLICATION}.
+     * In new code, prefer to work with Keystore namespaces directly.
+     * @hide
+     */
+    public static final int UID_SELF = -1;
+
+    /**
      * For legacy support, translate namespaces into known UIDs.
      * @hide
      */
     public static int namespaceToLegacyUid(@Namespace int namespace) {
         switch (namespace) {
             case NAMESPACE_APPLICATION:
-                return KeyStore.UID_SELF;
+                return UID_SELF;
             case NAMESPACE_WIFI:
                 return Process.WIFI_UID;
             default:
@@ -1029,7 +1035,7 @@
      */
     public static @Namespace int legacyUidToNamespace(int uid) {
         switch (uid) {
-            case KeyStore.UID_SELF:
+            case UID_SELF:
                 return NAMESPACE_APPLICATION;
             case Process.WIFI_UID:
                 return NAMESPACE_WIFI;
diff --git a/libs/WindowManager/Shell/aconfig/Android.bp b/libs/WindowManager/Shell/aconfig/Android.bp
index 1a98ffc..3891eeb 100644
--- a/libs/WindowManager/Shell/aconfig/Android.bp
+++ b/libs/WindowManager/Shell/aconfig/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "com_android_wm_shell_flags",
     package: "com.android.wm.shell",
+    container: "system",
     srcs: [
         "multitasking.aconfig",
     ],
@@ -9,4 +10,4 @@
 java_aconfig_library {
     name: "com_android_wm_shell_flags_lib",
     aconfig_declarations: "com_android_wm_shell_flags",
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 4511f3b..c0ecb8d 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.wm.shell"
+container: "system"
 
 flag {
     name: "example_flag"
diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
index 4f1a68a..a5bc261 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
@@ -65,6 +65,10 @@
     package_name: "com.android.wm.shell.flicker.service",
     instrumentation_target_package: "com.android.wm.shell.flicker.service",
     test_config_template: "AndroidTestTemplate.xml",
+    test_suites: [
+        "device-tests",
+        "device-platinum-tests",
+    ],
     srcs: [":WMShellFlickerServicePlatinumTests-src"],
     static_libs: ["WMShellFlickerTestsBase"],
     data: ["trace_config/*"],
diff --git a/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp
index b511244..6196589 100644
--- a/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp
+++ b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp
@@ -19,6 +19,7 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["frameworks_base_libs_androidfw_license"],
+    default_team: "trendy_team_android_resources",
 }
 
 cc_fuzz {
@@ -31,7 +32,7 @@
     static_libs: ["libgmock"],
     target: {
         android: {
-            shared_libs:[
+            shared_libs: [
                 "libandroidfw",
                 "libbase",
                 "libcutils",
@@ -52,4 +53,15 @@
             ],
         },
     },
+    fuzz_config: {
+        cc: [
+            "android-resources@google.com",
+        ],
+        componentid: 568761,
+        description: "The fuzzer targets the APIs of libandroidfw",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
+    },
 }
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 14e8653..656cb12 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -31,6 +31,7 @@
 aconfig_declarations {
     name: "hwui_flags",
     package: "com.android.graphics.hwui.flags",
+    container: "system",
     srcs: [
         "aconfig/hwui_flags.aconfig",
     ],
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index ca11975..920add5 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.graphics.hwui.flags"
+container: "system"
 
 flag {
   name: "matrix_44"
diff --git a/location/java/android/location/flags/gnss.aconfig b/location/java/android/location/flags/gnss.aconfig
index b6055e8..a3412de 100644
--- a/location/java/android/location/flags/gnss.aconfig
+++ b/location/java/android/location/flags/gnss.aconfig
@@ -1,4 +1,5 @@
 package: "android.location.flags"
+container: "system"
 
 flag {
     name: "gnss_api_navic_l1"
diff --git a/media/OWNERS b/media/OWNERS
index 1e5a458..5e39195 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -11,6 +11,7 @@
 nchalko@google.com
 philburk@google.com
 quxiangfang@google.com
+shuzhenwang@google.com
 wonsik@google.com
 
 # go/android-fwk-media-solutions for info on areas of ownership.
diff --git a/media/java/android/media/flags/fade_manager_configuration.aconfig b/media/java/android/media/flags/fade_manager_configuration.aconfig
index 100e2235..1f663dc 100644
--- a/media/java/android/media/flags/fade_manager_configuration.aconfig
+++ b/media/java/android/media/flags/fade_manager_configuration.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.media.flags"
+container: "system"
 
 flag {
     namespace: "media_solutions"
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 07f63e5..5276d22 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.media.flags"
+container: "system"
 
 flag {
     name: "enable_rlp_callbacks_in_media_router2"
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 018eaf6..baffb00 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -1,4 +1,5 @@
 package: "android.media.tv.flags"
+container: "system"
 
 flag {
     name: "broadcast_visibility_types"
diff --git a/media/jni/playback_flags.aconfig b/media/jni/playback_flags.aconfig
index 2bb0ec5..9d927ec 100644
--- a/media/jni/playback_flags.aconfig
+++ b/media/jni/playback_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.media.playback.flags"
+container: "system"
 
 flag {
   name: "mediametadataretriever_default_rgba8888"
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/OWNERS b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/OWNERS
new file mode 100644
index 0000000..f4f9c08
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1344
+include platform/frameworks/base:/media/OWNERS
+
+# Camera
+per-file *Camera* = file:platform/frameworks/av:/camera/OWNERS
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
index f03fc0a..0e40db6 100644
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ b/nfc/java/android/nfc/NfcActivityManager.java
@@ -195,16 +195,25 @@
             Bundle extras) {
         boolean isResumed;
         Binder token;
+        int pollTech, listenTech;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = getActivityState(activity);
             state.readerCallback = callback;
             state.readerModeFlags = flags;
             state.readerModeExtras = extras;
+            pollTech = state.mPollTech;
+            listenTech = state.mListenTech;
             token = state.token;
             isResumed = state.resumed;
         }
         if (isResumed) {
-            setReaderMode(token, flags, extras);
+            if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
+                    || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
+                throw new IllegalStateException(
+                    "Cannot be used when alternative DiscoveryTechnology is set");
+            } else {
+                setReaderMode(token, flags, extras);
+            }
         }
     }
 
@@ -385,15 +394,12 @@
         boolean readerModeFlagsSet;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = getActivityState(activity);
-            readerModeFlagsSet = state.readerModeFlags != 0;
             state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
             state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
             token = state.token;
             isResumed = state.resumed;
         }
-        if (readerModeFlagsSet) {
-            disableReaderMode(activity);
-        } else if (isResumed) {
+        if (isResumed) {
             changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
         }
 
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 7e0a111..e1c18843 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -1846,10 +1846,7 @@
                     throw new UnsupportedOperationException();
                 }
             }
-            mNfcActivityManager.enableReaderMode(activity, null, pollTechnology, null);
-            return;
-        }
-        if (pollTechnology == FLAG_READER_DISABLE) {
+        } else if (pollTechnology == FLAG_READER_DISABLE) {
             synchronized (sLock) {
                 if (!sHasCeFeature) {
                     throw new UnsupportedOperationException();
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index ad86d70..4bae118 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -970,16 +970,16 @@
      *
      * @param service The ComponentName of the service
      * @param status  true to enable, false to disable
+     * @param userId the user handle of the user whose information is being requested.
      * @return set service for the category and true if service is already set return false.
      *
      * @hide
      */
-    public boolean setServiceEnabledForCategoryOther(ComponentName service, boolean status) {
+    public boolean setServiceEnabledForCategoryOther(ComponentName service, boolean status,
+                                                     int userId) {
         if (service == null) {
             throw new NullPointerException("activity or service or category is null");
         }
-        int userId = mContext.getUser().getIdentifier();
-
         try {
             return sService.setServiceEnabledForCategoryOther(userId, service, status);
         } catch (RemoteException e) {
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index 7cd2533..ea3fd0d 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -481,6 +482,7 @@
      *
      * @param frame A description of the polling frame.
      */
+    @SuppressLint("OnNameExpected")
     @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
     public void processPollingFrames(@NonNull List<Bundle> frame) {
     }
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 5879595..4a6f26a 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.nfc"
+container: "system"
 
 flag {
     name: "enable_nfc_mainline"
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 25ac3c9..635dc42 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -172,7 +172,7 @@
 
     // This is for testing only now
     private boolean mEnableWhenCompleted;
-    private boolean mOneShot;
+    private boolean mOneShot = true;
     private boolean mHideNotification;
 
     private InstallationAsyncTask.Progress mInstallTaskProgress;
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 1e49330..91ac8fc7 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -75,6 +75,7 @@
 aconfig_declarations {
     name: "settingslib_media_flags",
     package: "com.android.settingslib.media.flags",
+    container: "system",
     srcs: [
         "aconfig/settingslib_media_flag_declarations.aconfig",
     ],
diff --git a/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig b/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
index f3e537b..4d70aec 100644
--- a/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib_media_flag_declarations.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.settingslib.media.flags"
+container: "system"
 
 flag {
   name: "use_media_router2_for_info_media_manager"
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
index 1ff2bef..5e3bd9a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
@@ -43,5 +43,5 @@
     /**
      * Bluetooth scheme.
      */
-    public static final String SCHEME_BT_BROADCAST_METADATA = "BT:";
+    public static final String SCHEME_BT_BROADCAST_METADATA = "BLUETOOTH:UUID:184F;";
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
index 9bb11f8..0c7d6f0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
@@ -31,38 +31,34 @@
 object BluetoothLeBroadcastMetadataExt {
     private const val TAG = "BtLeBroadcastMetadataExt"
 
-    // BluetoothLeBroadcastMetadata
-    private const val KEY_BT_QR_VER = "R"
-    private const val KEY_BT_ADDRESS_TYPE = "T"
-    private const val KEY_BT_DEVICE = "D"
-    private const val KEY_BT_ADVERTISING_SID = "AS"
-    private const val KEY_BT_BROADCAST_ID = "B"
+    // Data Elements for directing Broadcast Assistants
     private const val KEY_BT_BROADCAST_NAME = "BN"
-    private const val KEY_BT_PUBLIC_BROADCAST_DATA = "PM"
-    private const val KEY_BT_SYNC_INTERVAL = "SI"
-    private const val KEY_BT_BROADCAST_CODE = "C"
-    private const val KEY_BT_SUBGROUPS = "SG"
-    private const val KEY_BT_VENDOR_SPECIFIC = "V"
-    private const val KEY_BT_ANDROID_VERSION = "VN"
+    private const val KEY_BT_ADVERTISER_ADDRESS_TYPE = "AT"
+    private const val KEY_BT_ADVERTISER_ADDRESS = "AD"
+    private const val KEY_BT_BROADCAST_ID = "BI"
+    private const val KEY_BT_BROADCAST_CODE = "BC"
+    private const val KEY_BT_STREAM_METADATA = "MD"
+    private const val KEY_BT_STANDARD_QUALITY = "SQ"
+    private const val KEY_BT_HIGH_QUALITY = "HQ"
 
-    // Subgroup data
+    // Extended Bluetooth URI Data Elements
+    private const val KEY_BT_ADVERTISING_SID = "AS"
+    private const val KEY_BT_PA_INTERVAL = "PI"
+    private const val KEY_BT_NUM_SUBGROUPS = "NS"
+
+    // Subgroup data elements
     private const val KEY_BTSG_BIS_SYNC = "BS"
-    private const val KEY_BTSG_BIS_MASK = "BM"
-    private const val KEY_BTSG_AUDIO_CONTENT = "AC"
+    private const val KEY_BTSG_NUM_BISES = "NB"
+    private const val KEY_BTSG_METADATA = "SM"
 
-    // Vendor specific data
-    private const val KEY_BTVSD_COMPANY_ID = "VI"
-    private const val KEY_BTVSD_VENDOR_DATA = "VD"
+    // Vendor specific data, not being used
+    private const val KEY_BTVSD_VENDOR_DATA = "VS"
 
     private const val DELIMITER_KEY_VALUE = ":"
-    private const val DELIMITER_BT_LEVEL_1 = ";"
-    private const val DELIMITER_BT_LEVEL_2 = ","
+    private const val DELIMITER_ELEMENT = ";"
 
     private const val SUFFIX_QR_CODE = ";;"
 
-    private const val ANDROID_VER = "U"
-    private const val QR_CODE_VER = 0x010000
-
     // BT constants
     private const val BIS_SYNC_MAX_CHANNEL = 32
     private const val BIS_SYNC_NO_PREFERENCE = 0xFFFFFFFFu
@@ -71,33 +67,55 @@
     /**
      * Converts [BluetoothLeBroadcastMetadata] to QR code string.
      *
-     * QR code string will prefix with "BT:".
+     * QR code string will prefix with "BLUETOOTH:UUID:184F".
      */
     fun BluetoothLeBroadcastMetadata.toQrCodeString(): String {
         val entries = mutableListOf<Pair<String, String>>()
-        entries.add(Pair(KEY_BT_QR_VER, QR_CODE_VER.toString()))
-        entries.add(Pair(KEY_BT_ADDRESS_TYPE, this.sourceAddressType.toString()))
-        entries.add(Pair(KEY_BT_DEVICE, this.sourceDevice.address.replace(":", "-")))
-        entries.add(Pair(KEY_BT_ADVERTISING_SID, this.sourceAdvertisingSid.toString()))
-        entries.add(Pair(KEY_BT_BROADCAST_ID, this.broadcastId.toString()))
-        if (this.broadcastName != null) {
-            entries.add(Pair(KEY_BT_BROADCAST_NAME, Base64.encodeToString(
-                this.broadcastName?.toByteArray(Charsets.UTF_8), Base64.NO_WRAP)))
-        }
-        if (this.publicBroadcastMetadata != null) {
-            entries.add(Pair(KEY_BT_PUBLIC_BROADCAST_DATA, Base64.encodeToString(
-                this.publicBroadcastMetadata?.rawMetadata, Base64.NO_WRAP)))
-        }
-        entries.add(Pair(KEY_BT_SYNC_INTERVAL, this.paSyncInterval.toString()))
+        // Generate data elements for directing Broadcast Assistants
+        require(this.broadcastName != null) { "Broadcast name is mandatory for QR code" }
+        entries.add(Pair(KEY_BT_BROADCAST_NAME, Base64.encodeToString(
+            this.broadcastName?.toByteArray(Charsets.UTF_8), Base64.NO_WRAP)))
+        entries.add(Pair(KEY_BT_ADVERTISER_ADDRESS_TYPE, this.sourceAddressType.toString()))
+        entries.add(Pair(KEY_BT_ADVERTISER_ADDRESS, this.sourceDevice.address.replace(":", "")))
+        entries.add(Pair(KEY_BT_BROADCAST_ID, String.format("%X", this.broadcastId.toLong())))
         if (this.broadcastCode != null) {
             entries.add(Pair(KEY_BT_BROADCAST_CODE,
                 Base64.encodeToString(this.broadcastCode, Base64.NO_WRAP)))
         }
+        if (this.publicBroadcastMetadata != null &&
+                this.publicBroadcastMetadata?.rawMetadata?.size != 0) {
+            entries.add(Pair(KEY_BT_STREAM_METADATA, Base64.encodeToString(
+                this.publicBroadcastMetadata?.rawMetadata, Base64.NO_WRAP)))
+        }
+        if ((this.audioConfigQuality and
+                BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD) != 0) {
+            entries.add(Pair(KEY_BT_STANDARD_QUALITY, "1"))
+        }
+        if ((this.audioConfigQuality and
+                BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_HIGH) != 0) {
+            entries.add(Pair(KEY_BT_HIGH_QUALITY, "1"))
+        }
+
+        // Generate extended Bluetooth URI data elements
+        entries.add(Pair(KEY_BT_ADVERTISING_SID,
+                String.format("%X", this.sourceAdvertisingSid.toLong())))
+        entries.add(Pair(KEY_BT_PA_INTERVAL, String.format("%X", this.paSyncInterval.toLong())))
+        entries.add(Pair(KEY_BT_NUM_SUBGROUPS, String.format("%X", this.subgroups.size.toLong())))
+
         this.subgroups.forEach {
-                subgroup -> entries.add(Pair(KEY_BT_SUBGROUPS, subgroup.toQrCodeString())) }
-        entries.add(Pair(KEY_BT_ANDROID_VERSION, ANDROID_VER))
+            val (bisSync, bisCount) = getBisSyncFromChannels(it.channels)
+            entries.add(Pair(KEY_BTSG_BIS_SYNC, String.format("%X", bisSync.toLong())))
+            if (bisCount > 0u) {
+                entries.add(Pair(KEY_BTSG_NUM_BISES, String.format("%X", bisCount.toLong())))
+            }
+            if (it.contentMetadata.rawMetadata.size != 0) {
+                entries.add(Pair(KEY_BTSG_METADATA,
+                    Base64.encodeToString(it.contentMetadata.rawMetadata, Base64.NO_WRAP)))
+            }
+        }
+
         val qrCodeString = SCHEME_BT_BROADCAST_METADATA +
-                entries.toQrCodeString(DELIMITER_BT_LEVEL_1) + SUFFIX_QR_CODE
+                entries.toQrCodeString(DELIMITER_ELEMENT) + SUFFIX_QR_CODE
         Log.d(TAG, "Generated QR string : $qrCodeString")
         return qrCodeString
     }
@@ -105,7 +123,7 @@
     /**
      * Converts QR code string to [BluetoothLeBroadcastMetadata].
      *
-     * QR code string should prefix with "BT:BluetoothLeBroadcastMetadata:".
+     * QR code string should prefix with "BLUETOOTH:UUID:184F".
      */
     fun convertToBroadcastMetadata(qrCodeString: String): BluetoothLeBroadcastMetadata? {
         if (!qrCodeString.startsWith(SCHEME_BT_BROADCAST_METADATA)) {
@@ -126,15 +144,6 @@
         }
     }
 
-    private fun BluetoothLeBroadcastSubgroup.toQrCodeString(): String {
-        val entries = mutableListOf<Pair<String, String>>()
-        entries.add(Pair(KEY_BTSG_BIS_SYNC, getBisSyncFromChannels(this.channels).toString()))
-        entries.add(Pair(KEY_BTSG_BIS_MASK, getBisMaskFromChannels(this.channels).toString()))
-        entries.add(Pair(KEY_BTSG_AUDIO_CONTENT,
-            Base64.encodeToString(this.contentMetadata.rawMetadata, Base64.NO_WRAP)))
-        return entries.toQrCodeString(DELIMITER_BT_LEVEL_2)
-    }
-
     private fun List<Pair<String, String>>.toQrCodeString(delimiter: String): String {
         val entryStrings = this.map{ it.first + DELIMITER_KEY_VALUE + it.second }
         return entryStrings.joinToString(separator = delimiter)
@@ -143,23 +152,29 @@
     @TargetApi(Build.VERSION_CODES.TIRAMISU)
     private fun parseQrCodeToMetadata(input: String): BluetoothLeBroadcastMetadata {
         // Split into a list of list
-        val level1Fields = input.split(DELIMITER_BT_LEVEL_1)
+        val elementFields = input.split(DELIMITER_ELEMENT)
             .map{it.split(DELIMITER_KEY_VALUE, limit = 2)}
-        var qrCodeVersion = -1
+
         var sourceAddrType = BluetoothDevice.ADDRESS_TYPE_UNKNOWN
         var sourceAddrString: String? = null
         var sourceAdvertiserSid = -1
         var broadcastId = -1
         var broadcastName: String? = null
-        var publicBroadcastMetadata: BluetoothLeAudioContentMetadata? = null
+        var streamMetadata: BluetoothLeAudioContentMetadata? = null
         var paSyncInterval = -1
         var broadcastCode: ByteArray? = null
-        // List of VendorID -> Data Pairs
-        var vendorDataList = mutableListOf<Pair<Int, ByteArray?>>()
-        var androidVersion: String? = null
+        var audioConfigQualityStandard = -1
+        var audioConfigQualityHigh = -1
+        var numSubgroups = -1
+
+        // List of subgroup data
+        var subgroupBisSyncList = mutableListOf<UInt>()
+        var subgroupNumOfBisesList = mutableListOf<UInt>()
+        var subgroupMetadataList = mutableListOf<ByteArray?>()
+
         val builder = BluetoothLeBroadcastMetadata.Builder()
 
-        for (field: List<String> in level1Fields) {
+        for (field: List<String> in elementFields) {
             if (field.isEmpty()) {
                 continue
             }
@@ -167,190 +182,200 @@
             // Ignore 3rd value and after
             val value = if (field.size > 1) field[1] else ""
             when (key) {
-                KEY_BT_QR_VER -> {
-                    require(qrCodeVersion == -1) { "Duplicate qrCodeVersion: $input" }
-                    qrCodeVersion = value.toInt()
+                // Parse data elements for directing Broadcast Assistants
+                KEY_BT_BROADCAST_NAME -> {
+                    require(broadcastName == null) { "Duplicate broadcastName: $input" }
+                    broadcastName = String(Base64.decode(value, Base64.NO_WRAP))
                 }
-                KEY_BT_ADDRESS_TYPE -> {
+                KEY_BT_ADVERTISER_ADDRESS_TYPE -> {
                     require(sourceAddrType == BluetoothDevice.ADDRESS_TYPE_UNKNOWN) {
                         "Duplicate sourceAddrType: $input"
                     }
                     sourceAddrType = value.toInt()
                 }
-                KEY_BT_DEVICE -> {
+                KEY_BT_ADVERTISER_ADDRESS -> {
                     require(sourceAddrString == null) { "Duplicate sourceAddr: $input" }
-                    sourceAddrString = value.replace("-", ":")
-                }
-                KEY_BT_ADVERTISING_SID -> {
-                    require(sourceAdvertiserSid == -1) { "Duplicate sourceAdvertiserSid: $input" }
-                    sourceAdvertiserSid = value.toInt()
+                    sourceAddrString = value.chunked(2).joinToString(":")
                 }
                 KEY_BT_BROADCAST_ID -> {
                     require(broadcastId == -1) { "Duplicate broadcastId: $input" }
-                    broadcastId = value.toInt()
-                }
-                KEY_BT_BROADCAST_NAME -> {
-                    require(broadcastName == null) { "Duplicate broadcastName: $input" }
-                    broadcastName = String(Base64.decode(value, Base64.NO_WRAP))
-                }
-                KEY_BT_PUBLIC_BROADCAST_DATA -> {
-                    require(publicBroadcastMetadata == null) {
-                        "Duplicate publicBroadcastMetadata $input"
-                    }
-                    publicBroadcastMetadata = BluetoothLeAudioContentMetadata
-                        .fromRawBytes(Base64.decode(value, Base64.NO_WRAP))
-                }
-                KEY_BT_SYNC_INTERVAL -> {
-                    require(paSyncInterval == -1) { "Duplicate paSyncInterval: $input" }
-                    paSyncInterval = value.toInt()
+                    broadcastId = value.toInt(16)
                 }
                 KEY_BT_BROADCAST_CODE -> {
                     require(broadcastCode == null) { "Duplicate broadcastCode: $input" }
-                    broadcastCode = Base64.decode(value, Base64.NO_WRAP)
+
+                    broadcastCode = Base64.decode(value.dropLastWhile { it.equals(0.toByte()) }
+                            .toByteArray(), Base64.NO_WRAP)
                 }
-                KEY_BT_ANDROID_VERSION -> {
-                    require(androidVersion == null) { "Duplicate androidVersion: $input" }
-                    androidVersion = value
-                    Log.i(TAG, "QR code Android version: $androidVersion")
+                KEY_BT_STREAM_METADATA -> {
+                    require(streamMetadata == null) {
+                        "Duplicate streamMetadata $input"
+                    }
+                    streamMetadata = BluetoothLeAudioContentMetadata
+                        .fromRawBytes(Base64.decode(value, Base64.NO_WRAP))
                 }
-                // Repeatable
-                KEY_BT_SUBGROUPS -> {
-                    builder.addSubgroup(parseSubgroupData(value))
+                KEY_BT_STANDARD_QUALITY -> {
+                    require(audioConfigQualityStandard == -1) {
+                        "Duplicate audioConfigQualityStandard: $input"
+                    }
+                    audioConfigQualityStandard = value.toInt()
                 }
-                // Repeatable
-                KEY_BT_VENDOR_SPECIFIC -> {
-                    vendorDataList.add(parseVendorData(value))
+                KEY_BT_HIGH_QUALITY -> {
+                    require(audioConfigQualityHigh == -1) {
+                        "Duplicate audioConfigQualityHigh: $input"
+                    }
+                    audioConfigQualityHigh = value.toInt()
+                }
+
+                // Parse extended Bluetooth URI data elements
+                KEY_BT_ADVERTISING_SID -> {
+                    require(sourceAdvertiserSid == -1) { "Duplicate sourceAdvertiserSid: $input" }
+                    sourceAdvertiserSid = value.toInt(16)
+                }
+                KEY_BT_PA_INTERVAL -> {
+                    require(paSyncInterval == -1) { "Duplicate paSyncInterval: $input" }
+                    paSyncInterval = value.toInt(16)
+                }
+                KEY_BT_NUM_SUBGROUPS -> {
+                    require(numSubgroups == -1) { "Duplicate numSubgroups: $input" }
+                    numSubgroups = value.toInt(16)
+                }
+
+                // Repeatable subgroup elements
+                KEY_BTSG_BIS_SYNC -> {
+                    subgroupBisSyncList.add(value.toUInt(16))
+                }
+                KEY_BTSG_NUM_BISES -> {
+                    subgroupNumOfBisesList.add(value.toUInt(16))
+                }
+                KEY_BTSG_METADATA -> {
+                    subgroupMetadataList.add(Base64.decode(value, Base64.NO_WRAP))
                 }
             }
         }
-        Log.d(TAG, "parseQrCodeToMetadata: sourceAddrType=$sourceAddrType, " +
+        Log.d(TAG, "parseQrCodeToMetadata: main data elements sourceAddrType=$sourceAddrType, " +
                 "sourceAddr=$sourceAddrString, sourceAdvertiserSid=$sourceAdvertiserSid, " +
                 "broadcastId=$broadcastId, broadcastName=$broadcastName, " +
-                "publicBroadcastMetadata=${publicBroadcastMetadata != null}, " +
+                "streamMetadata=${streamMetadata != null}, " +
                 "paSyncInterval=$paSyncInterval, " +
-                "broadcastCode=${broadcastCode?.toString(Charsets.UTF_8)}")
-        Log.d(TAG, "Not used in current code, but part of the specification: " +
-                "qrCodeVersion=$qrCodeVersion, androidVersion=$androidVersion, " +
-                "vendorDataListSize=${vendorDataList.size}")
+                "broadcastCode=${broadcastCode?.toString(Charsets.UTF_8)}, " +
+                "audioConfigQualityStandard=$audioConfigQualityStandard, " +
+                "audioConfigQualityHigh=$audioConfigQualityHigh")
+
         val adapter = BluetoothAdapter.getDefaultAdapter()
+        // Check parsed elements data
+        require(broadcastName != null) {
+            "broadcastName($broadcastName) must present in QR code string"
+        }
+        var addr = sourceAddrString
+        var addrType = sourceAddrType
+        if (sourceAddrString != null) {
+            require(sourceAddrType != BluetoothDevice.ADDRESS_TYPE_UNKNOWN) {
+                "sourceAddrType($sourceAddrType) must present if address present"
+            }
+        } else {
+            // Use placeholder device if not present
+            addr = "FF:FF:FF:FF:FF:FF"
+            addrType = BluetoothDevice.ADDRESS_TYPE_RANDOM
+        }
+        val device = adapter.getRemoteLeDevice(requireNotNull(addr), addrType)
+
         // add source device and set broadcast code
-        val device = adapter.getRemoteLeDevice(requireNotNull(sourceAddrString), sourceAddrType)
+        var audioConfigQuality = BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_NONE or
+                (if (audioConfigQualityStandard != -1) audioConfigQualityStandard else 0) or
+                (if (audioConfigQualityHigh != -1) audioConfigQualityHigh else 0)
+
+        // process subgroup data
+        // metadata should include at least 1 subgroup for metadata, add a placeholder group if not present
+        numSubgroups = if (numSubgroups > 0) numSubgroups else 1
+        for (i in 0 until numSubgroups) {
+            val bisSync = subgroupBisSyncList.getOrNull(i)
+            val bisNum = subgroupNumOfBisesList.getOrNull(i)
+            val metadata = subgroupMetadataList.getOrNull(i)
+
+            val channels = convertToChannels(bisSync, bisNum)
+            val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
+                    .setAudioLocation(0).build()
+            val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+                setCodecId(SUBGROUP_LC3_CODEC_ID)
+                setCodecSpecificConfig(audioCodecConfigMetadata)
+                setContentMetadata(
+                        BluetoothLeAudioContentMetadata.fromRawBytes(metadata ?: ByteArray(0)))
+                channels.forEach(::addChannel)
+            }.build()
+
+            Log.d(TAG, "parseQrCodeToMetadata: subgroup $i elements bisSync=$bisSync, " +
+                    "bisNum=$bisNum, metadata=${metadata != null}")
+
+            builder.addSubgroup(subgroup)
+        }
+
         builder.apply {
-            setSourceDevice(device, sourceAddrType)
+            setSourceDevice(device, addrType)
             setSourceAdvertisingSid(sourceAdvertiserSid)
             setBroadcastId(broadcastId)
             setBroadcastName(broadcastName)
-            setPublicBroadcast(publicBroadcastMetadata != null)
-            setPublicBroadcastMetadata(publicBroadcastMetadata)
+            // QR code should set PBP(public broadcast profile) for auracast
+            setPublicBroadcast(true)
+            setPublicBroadcastMetadata(streamMetadata)
             setPaSyncInterval(paSyncInterval)
             setEncrypted(broadcastCode != null)
             setBroadcastCode(broadcastCode)
             // Presentation delay is unknown and not useful when adding source
             // Broadcast sink needs to sync to the Broadcast source to get presentation delay
             setPresentationDelayMicros(0)
+            setAudioConfigQuality(audioConfigQuality)
         }
         return builder.build()
     }
 
-    private fun parseSubgroupData(input: String): BluetoothLeBroadcastSubgroup {
-        Log.d(TAG, "parseSubgroupData: $input")
-        val fields = input.split(DELIMITER_BT_LEVEL_2)
-        var bisSync: UInt? = null
-        var bisMask: UInt? = null
-        var metadata: ByteArray? = null
-
-        fields.forEach { field ->
-            val(key, value) = field.split(DELIMITER_KEY_VALUE)
-            when (key) {
-                KEY_BTSG_BIS_SYNC -> {
-                    require(bisSync == null) { "Duplicate bisSync: $input" }
-                    bisSync = value.toUInt()
-                }
-                KEY_BTSG_BIS_MASK -> {
-                    require(bisMask == null) { "Duplicate bisMask: $input" }
-                    bisMask = value.toUInt()
-                }
-                KEY_BTSG_AUDIO_CONTENT -> {
-                    require(metadata == null) { "Duplicate metadata: $input" }
-                    metadata = Base64.decode(value, Base64.NO_WRAP)
-                }
-            }
-        }
-        val channels = convertToChannels(requireNotNull(bisSync), requireNotNull(bisMask))
-        val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
-                .setAudioLocation(0).build()
-        return BluetoothLeBroadcastSubgroup.Builder().apply {
-            setCodecId(SUBGROUP_LC3_CODEC_ID)
-            setCodecSpecificConfig(audioCodecConfigMetadata)
-            setContentMetadata(
-                    BluetoothLeAudioContentMetadata.fromRawBytes(metadata ?: ByteArray(0)))
-            channels.forEach(::addChannel)
-        }.build()
-    }
-
-    private fun parseVendorData(input: String): Pair<Int, ByteArray?> {
-        var companyId = -1
-        var data: ByteArray? = null
-        val fields = input.split(DELIMITER_BT_LEVEL_2)
-        fields.forEach { field ->
-            val(key, value) = field.split(DELIMITER_KEY_VALUE)
-            when (key) {
-                KEY_BTVSD_COMPANY_ID -> {
-                    require(companyId == -1) { "Duplicate companyId: $input" }
-                    companyId = value.toInt()
-                }
-                KEY_BTVSD_VENDOR_DATA -> {
-                    require(data == null) { "Duplicate data: $input" }
-                    data = Base64.decode(value, Base64.NO_WRAP)
-                }
-            }
-        }
-        return Pair(companyId, data)
-    }
-
-    private fun getBisSyncFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
+    private fun getBisSyncFromChannels(
+        channels: List<BluetoothLeBroadcastChannel>
+    ): Pair<UInt, UInt> {
         var bisSync = 0u
-        // channel index starts from 1
-        channels.forEach { channel ->
-            if (channel.isSelected && channel.channelIndex > 0) {
-                bisSync = bisSync or (1u shl (channel.channelIndex - 1))
-            }
-        }
-        // No channel is selected means no preference on Android platform
-        return if (bisSync == 0u) BIS_SYNC_NO_PREFERENCE else bisSync
-    }
-
-    private fun getBisMaskFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
-        var bisMask = 0u
+        var bisCount = 0u
         // channel index starts from 1
         channels.forEach { channel ->
             if (channel.channelIndex > 0) {
-                bisMask = bisMask or (1u shl (channel.channelIndex - 1))
+                bisCount++
+                if (channel.isSelected) {
+                    bisSync = bisSync or (1u shl (channel.channelIndex - 1))
+                }
             }
         }
-        return bisMask
+        // No channel is selected means no preference on Android platform
+        return if (bisSync == 0u) Pair(BIS_SYNC_NO_PREFERENCE, bisCount)
+                else Pair(bisSync, bisCount)
     }
 
-    private fun convertToChannels(bisSync: UInt, bisMask: UInt):
-            List<BluetoothLeBroadcastChannel> {
-        Log.d(TAG, "convertToChannels: bisSync=$bisSync, bisMask=$bisMask")
-        var selectionMask = bisSync
-        if (bisSync != BIS_SYNC_NO_PREFERENCE) {
-            require(bisMask == (bisMask or bisSync)) {
-                "bisSync($bisSync) must select a subset of bisMask($bisMask) if it has preferences"
-            }
-        } else {
-            // No channel preference means no channel is selected
-            selectionMask = 0u
-        }
+    private fun convertToChannels(
+        bisSync: UInt?,
+        bisNum: UInt?
+    ): List<BluetoothLeBroadcastChannel> {
+        Log.d(TAG, "convertToChannels: bisSync=$bisSync, bisNum=$bisNum")
+        // if no BIS_SYNC or BIS_NUM available or BIS_SYNC is no preference
+        // return empty channel map with one placeholder channel
+        var selectedChannels = if (bisSync != null && bisNum != null) bisSync else 0u
         val channels = mutableListOf<BluetoothLeBroadcastChannel>()
         val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
                 .setAudioLocation(0).build()
+
+        if (bisSync == BIS_SYNC_NO_PREFERENCE || selectedChannels == 0u) {
+            // No channel preference means no channel is selected
+            // Generate one placeholder channel for metadata
+            val channel = BluetoothLeBroadcastChannel.Builder().apply {
+                setSelected(false)
+                setChannelIndex(1)
+                setCodecMetadata(audioCodecConfigMetadata)
+            }
+            return listOf(channel.build())
+        }
+
         for (i in 0 until BIS_SYNC_MAX_CHANNEL) {
             val channelMask = 1u shl i
-            if ((bisMask and channelMask) != 0u) {
+            if ((selectedChannels and channelMask) != 0u) {
                 val channel = BluetoothLeBroadcastChannel.Builder().apply {
-                    setSelected((selectionMask and channelMask) != 0u)
+                    setSelected(true)
                     setChannelIndex(i + 1)
                     setCodecMetadata(audioCodecConfigMetadata)
                 }
diff --git a/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
index 27d7078..1ad20dc 100644
--- a/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
+++ b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
@@ -32,7 +32,7 @@
 class BluetoothLeBroadcastMetadataExtTest {
 
     @Test
-    fun toQrCodeString() {
+    fun toQrCodeString_encrypted() {
         val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
             setCodecId(0x6)
             val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
@@ -70,6 +70,37 @@
     }
 
     @Test
+    fun toQrCodeString_non_encrypted() {
+        val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+            setCodecId(0x6)
+            val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+            setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+                .build())
+            setCodecSpecificConfig(audioCodecConfigMetadata)
+            addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+                setSelected(true)
+                setChannelIndex(1)
+                setCodecMetadata(audioCodecConfigMetadata)
+            }.build())
+        }.build()
+
+        val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+            setSourceDevice(DevicePublic, BluetoothDevice.ADDRESS_TYPE_PUBLIC)
+            setSourceAdvertisingSid(1)
+            setBroadcastId(0xDE51E9)
+            setBroadcastName("Hockey")
+            setAudioConfigQuality(BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD)
+            setPaSyncInterval(0xFFFF)
+            setEncrypted(false)
+            addSubgroup(subgroup)
+        }.build()
+
+        val qrCodeString = metadata.toQrCodeString()
+
+        assertThat(qrCodeString).isEqualTo(QR_CODE_STRING_NON_ENCRYPTED)
+    }
+
+    @Test
     fun toQrCodeString_NoChannelSelected() {
         val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
             setCodecId(0x6)
@@ -102,6 +133,7 @@
             addSubgroup(subgroup)
         }.build()
 
+        // if no channel is selected, no preference(0xFFFFFFFFu) will be set in BIS
         val qrCodeString = metadata.toQrCodeString()
 
         val parsedMetadata =
@@ -111,13 +143,11 @@
         assertThat(parsedMetadata.subgroups).isNotNull()
         assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
         assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
-        assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+        assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(1)
         assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isFalse()
-        // Input order does not matter due to parsing through bisMask
+        // placeholder channel with not selected
         assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
         assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
-        assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
-        assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isFalse()
     }
 
     @Test
@@ -162,13 +192,11 @@
         assertThat(parsedMetadata.subgroups).isNotNull()
         assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
         assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
-        // Only selected channel can be recovered
-        assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+        // Only selected channel can be recovered, non-selected ones will be ignored
+        assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(1)
         assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isTrue()
-        assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
-        assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
-        assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
-        assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isTrue()
+        assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(2)
+        assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isTrue()
     }
 
     @Test
@@ -180,16 +208,34 @@
         assertThat(qrCodeString).isEqualTo(QR_CODE_STRING)
     }
 
+    @Test
+    fun decodeAndEncodeAgain_sameString_non_encrypted() {
+        val metadata =
+                BluetoothLeBroadcastMetadataExt
+                        .convertToBroadcastMetadata(QR_CODE_STRING_NON_ENCRYPTED)!!
+
+        val qrCodeString = metadata.toQrCodeString()
+
+        assertThat(qrCodeString).isEqualTo(QR_CODE_STRING_NON_ENCRYPTED)
+    }
+
     private companion object {
         const val TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"
+        const val TEST_DEVICE_ADDRESS_PUBLIC = "AA:BB:CC:00:11:22"
 
         val Device: BluetoothDevice =
             BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS,
                 BluetoothDevice.ADDRESS_TYPE_RANDOM)
 
+        val DevicePublic: BluetoothDevice =
+            BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS_PUBLIC,
+                BluetoothDevice.ADDRESS_TYPE_PUBLIC)
+
         const val QR_CODE_STRING =
-            "BT:R:65536;T:1;D:00-A1-A1-A1-A1-A1;AS:1;B:123456;BN:VGVzdA==;" +
-            "PM:BgNwVGVzdA==;SI:160;C:VGVzdENvZGU=;SG:BS:3,BM:3,AC:BQNUZXN0BARlbmc=;" +
-            "VN:U;;"
+            "BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;" +
+            "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;"
+        const val QR_CODE_STRING_NON_ENCRYPTED =
+            "BLUETOOTH:UUID:184F;BN:SG9ja2V5;AT:0;AD:AABBCC001122;BI:DE51E9;SQ:1;AS:1;PI:FFFF;" +
+            "NS:1;BS:1;NB:1;;"
     }
 }
\ No newline at end of file
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index adebdcd..cfe664e 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -83,6 +83,7 @@
 aconfig_declarations {
     name: "device_config_service_flags",
     package: "com.android.providers.settings",
+    container: "system",
     srcs: [
         "src/com/android/providers/settings/device_config_service.aconfig",
     ],
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
index 27ce0d4..b3ed1e91 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
+++ b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.providers.settings"
+container: "system"
 
 flag {
     name: "support_overrides"
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index bacab0f..00e17f5 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -602,6 +602,8 @@
 
     <!-- Permission required for CTS test - CtsThreadNetworkTestCases -->
     <uses-permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED"/>
+    <!-- Permission required to access Thread network shell commands for testing -->
+    <uses-permission android:name="android.permission.THREAD_NETWORK_TESTING"/>
 
     <!-- Permission required for CTS tests to enable/disable rate limiting toasts. -->
     <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" />
diff --git a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
index ee81813..0dd9275 100644
--- a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
+++ b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
@@ -36,6 +36,7 @@
 import android.os.UserManager;
 import android.provider.MediaStore;
 import android.provider.Settings;
+import android.text.Html;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
@@ -253,6 +254,9 @@
             } else {
                 p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title);
             }
+        } else {
+            // Make sure intents don't inject HTML elements.
+            p.mTitle = Html.escapeHtml(p.mTitle.toString());
         }
 
         setupAlert();
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
index 6d63409..ff75d8c 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "com_android_a11y_menu_flags",
     package: "com.android.systemui.accessibility.accessibilitymenu",
+    container: "system",
     srcs: [
         "accessibility.aconfig",
     ],
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
index eadcd7c..6ad1b38 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui.accessibility.accessibilitymenu"
+container: "system"
 
 # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
 
diff --git a/packages/SystemUI/aconfig/Android.bp b/packages/SystemUI/aconfig/Android.bp
index 50ed7ab..b09d1da 100644
--- a/packages/SystemUI/aconfig/Android.bp
+++ b/packages/SystemUI/aconfig/Android.bp
@@ -23,13 +23,14 @@
     default_visibility: [
         "//visibility:override",
         "//frameworks/base/packages/SystemUI:__subpackages__",
-        "//platform_testing:__subpackages__"
+        "//platform_testing:__subpackages__",
     ],
 }
 
 aconfig_declarations {
     name: "com_android_systemui_flags",
     package: "com.android.systemui",
+    container: "system",
     srcs: [
         "*.aconfig",
     ],
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 21263a9..97bf8d8 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
 
@@ -28,4 +29,4 @@
     namespace: "accessibility"
     description: "Animates the floating menu's transition between curved and jagged edges."
     bug: "281140482"
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
index 5fd3b48..e6c6974 100644
--- a/packages/SystemUI/aconfig/biometrics_framework.aconfig
+++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
 
@@ -7,4 +8,4 @@
     namespace: "biometrics_framework"
     description: "Adds talkback directional guidance when using UDFPS with biometric prompt"
     bug: "310044658"
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/aconfig/communal.aconfig b/packages/SystemUI/aconfig/communal.aconfig
index 2c6ff97..2e9af7e 100644
--- a/packages/SystemUI/aconfig/communal.aconfig
+++ b/packages/SystemUI/aconfig/communal.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 flag {
     name: "communal_hub"
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index facb244..27977c0 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 flag {
     name: "example_flag"
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 95f7c94a..73eeed8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -619,6 +619,7 @@
     private int mDreamingToLockscreenTransitionTranslationY;
     private int mLockscreenToDreamingTransitionTranslationY;
     private int mGoneToDreamingTransitionTranslationY;
+    private boolean mForceFlingAnimationForTest = false;
     private SplitShadeStateController mSplitShadeStateController;
     private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
             mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */);
@@ -2174,11 +2175,19 @@
                 }
             }
         });
+        if (!mScrimController.isScreenOn() && !mForceFlingAnimationForTest) {
+            animator.setDuration(1);
+        }
         setAnimator(animator);
         animator.start();
     }
 
     @VisibleForTesting
+    void setForceFlingAnimationForTest(boolean force) {
+        mForceFlingAnimationForTest = force;
+    }
+
+    @VisibleForTesting
     void onFlingEnd(boolean cancelled) {
         mIsFlinging = false;
         // No overshoot when the animation ends
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index ae04eaf..dd42ba99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -1588,6 +1588,10 @@
         mScreenOn = false;
     }
 
+    public boolean isScreenOn() {
+        return mScreenOn;
+    }
+
     public void setExpansionAffectsAlpha(boolean expansionAffectsAlpha) {
         mExpansionAffectsAlpha = expansionAffectsAlpha;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 28fe8e4..c131c32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -387,6 +387,7 @@
     public void testOnTouchEvent_expansionResumesAfterBriefTouch() {
         mFalsingManager.setIsClassifierEnabled(true);
         mFalsingManager.setIsFalseTouch(false);
+        mNotificationPanelViewController.setForceFlingAnimationForTest(true);
         // Start shade collapse with swipe up
         onTouchEvent(MotionEvent.obtain(0L /* downTime */,
                 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
@@ -415,6 +416,7 @@
         // fling should still be called after a touch that does not exceed touch slop
         assertThat(mNotificationPanelViewController.isClosing()).isTrue();
         assertThat(mNotificationPanelViewController.isFlinging()).isTrue();
+        mNotificationPanelViewController.setForceFlingAnimationForTest(false);
     }
 
     @Test
diff --git a/proto/src/am_capabilities.proto b/proto/src/am_capabilities.proto
index fc9f7a45..c2b3ac2 100644
--- a/proto/src/am_capabilities.proto
+++ b/proto/src/am_capabilities.proto
@@ -15,8 +15,16 @@
   string name  = 1;
 }
 
+message VMInfo {
+  // The value of the "java.vm.name" system property
+  string name = 1;
+  // The value of the "java.vm.version" system property
+  string version = 2;
+}
+
 message Capabilities {
   repeated Capability values = 1;
   repeated VMCapability vm_capabilities = 2;
   repeated FrameworkCapability framework_capabilities = 3;
+  VMInfo vm_info = 4;
 }
diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS
index 41fd68e..a90328c 100644
--- a/ravenwood/OWNERS
+++ b/ravenwood/OWNERS
@@ -2,4 +2,6 @@
 
 jsharkey@google.com
 omakoto@google.com
-jaggies@google.com
+
+per-file ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com
+per-file texts/ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
index 13908f1..56eb658 100644
--- a/ravenwood/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -1,5 +1,7 @@
 # Only classes listed here can use the Ravenwood annotations.
 
+com.android.internal.ravenwood.*
+
 com.android.internal.util.ArrayUtils
 com.android.internal.os.BatteryStatsHistory
 com.android.internal.os.BatteryStatsHistory$TraceDelegate
diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp
index e2488a5..898b7d6 100644
--- a/services/accessibility/Android.bp
+++ b/services/accessibility/Android.bp
@@ -54,6 +54,7 @@
 aconfig_declarations {
     name: "com_android_server_accessibility_flags",
     package: "com.android.server.accessibility",
+    container: "system",
     srcs: [
         "accessibility.aconfig",
     ],
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index a19920f..f54610a 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.accessibility"
+container: "system"
 
 # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
 
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index a4b2896..96ae790 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -5084,7 +5084,9 @@
                         // so we tear it down in anticipation of it (possibly) being
                         // reconstructed due to the restore
                         host.widgets.remove(widget);
-                        provider.widgets.remove(widget);
+                        if (provider != null) {
+                            provider.widgets.remove(widget);
+                        }
                         // Check if we need to destroy any services (if no other app widgets are
                         // referencing the same service)
                         decrementAppWidgetServiceRefCount(widget);
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index b5130a1..e0d67e8 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.autofill"
+container: "system"
 
 flag {
   name: "test"
diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig
index 92e00ee..eef1163 100644
--- a/services/autofill/features.aconfig
+++ b/services/autofill/features.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.autofill"
+container: "system"
 
 flag {
   name: "autofill_credman_integration"
diff --git a/services/backup/Android.bp b/services/backup/Android.bp
index d08a97e..dd36b25 100644
--- a/services/backup/Android.bp
+++ b/services/backup/Android.bp
@@ -31,6 +31,7 @@
 aconfig_declarations {
     name: "backup_flags",
     package: "com.android.server.backup",
+    container: "system",
     srcs: ["flags.aconfig"],
 }
 
diff --git a/services/backup/flags.aconfig b/services/backup/flags.aconfig
index d695d36..2186169f 100644
--- a/services/backup/flags.aconfig
+++ b/services/backup/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.backup"
+container: "system"
 
 flag {
     name: "enable_skipping_restore_launched_apps"
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 0e66fbc..71a1822 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -23,6 +23,7 @@
 import android.os.Build;
 import android.util.Slog;
 
+import com.google.security.cryptauth.lib.securegcm.ukey2.AlertException;
 import com.google.security.cryptauth.lib.securegcm.ukey2.BadHandleException;
 import com.google.security.cryptauth.lib.securegcm.ukey2.CryptoException;
 import com.google.security.cryptauth.lib.securegcm.ukey2.D2DConnectionContextV1;
@@ -203,7 +204,8 @@
      *
      * This method must only be called from one of the two participants.
      */
-    public void establishSecureConnection() throws IOException, SecureChannelException {
+    public void establishSecureConnection() throws IOException,
+            SecureChannelException, HandshakeException {
         if (isSecured()) {
             Slog.d(TAG, "Channel is already secure.");
             return;
@@ -334,7 +336,7 @@
         }
     }
 
-    private void initiateHandshake() throws IOException, BadHandleException {
+    private void initiateHandshake() throws IOException, BadHandleException , HandshakeException {
         if (mConnectionContext != null) {
             Slog.d(TAG, "Ukey2 handshake is already completed.");
             return;
@@ -394,8 +396,8 @@
         }
     }
 
-    private void exchangeHandshake()
-            throws IOException, HandshakeException, BadHandleException, CryptoException {
+    private void exchangeHandshake() throws IOException, HandshakeException,
+            BadHandleException, CryptoException, AlertException {
         if (mConnectionContext != null) {
             Slog.d(TAG, "Ukey2 handshake is already completed.");
             return;
diff --git a/services/companion/java/com/android/server/companion/virtual/Android.bp b/services/companion/java/com/android/server/companion/virtual/Android.bp
index 6526c78..1d00e9b 100644
--- a/services/companion/java/com/android/server/companion/virtual/Android.bp
+++ b/services/companion/java/com/android/server/companion/virtual/Android.bp
@@ -6,6 +6,7 @@
 aconfig_declarations {
     name: "virtualdevice_flags",
     package: "com.android.server.companion.virtual",
+    container: "system",
     srcs: [
         "flags.aconfig",
     ],
diff --git a/services/companion/java/com/android/server/companion/virtual/flags.aconfig b/services/companion/java/com/android/server/companion/virtual/flags.aconfig
index 6297e91..616f5d0 100644
--- a/services/companion/java/com/android/server/companion/virtual/flags.aconfig
+++ b/services/companion/java/com/android/server/companion/virtual/flags.aconfig
@@ -1,6 +1,7 @@
 # OLD PACKAGE, DO NOT USE: Prefer `flags.aconfig` in core/java/android/companion/virtual
 # (or other custom files) to define your flags
 package: "com.android.server.companion.virtual"
+container: "system"
 
 flag {
   name: "dump_history"
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 9f279b1..f69a521 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -34,6 +34,7 @@
 import android.provider.Downloads;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.AtomicFile;
 import android.util.EventLog;
@@ -230,16 +231,23 @@
     }
 
     private static String getCurrentBootHeaders() throws IOException {
-        return new StringBuilder(512)
-            .append("Build: ").append(Build.FINGERPRINT).append("\n")
-            .append("Hardware: ").append(Build.BOARD).append("\n")
-            .append("Revision: ")
-            .append(SystemProperties.get("ro.revision", "")).append("\n")
-            .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
-            .append("Radio: ").append(Build.getRadioVersion()).append("\n")
-            .append("Kernel: ")
-            .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
-            .append("\n").toString();
+        StringBuilder builder =  new StringBuilder(512)
+                .append("Build: ").append(Build.FINGERPRINT).append("\n")
+                .append("Hardware: ").append(Build.BOARD).append("\n")
+                .append("Revision: ")
+                .append(SystemProperties.get("ro.revision", "")).append("\n")
+                .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
+                .append("Radio: ").append(Build.getRadioVersion()).append("\n")
+                .append("Kernel: ")
+                .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));
+
+        // If device is not using 4KB pages, add the PageSize
+        long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+        if (pageSize != 4096) {
+            builder.append("PageSize: ").append(pageSize).append("\n");
+        }
+        builder.append("\n");
+        return builder.toString();
     }
 
 
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index a619257..966478e 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -138,6 +138,12 @@
 
     static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10);
 
+    // Time needed to apply mitigation
+    private static final String MITIGATION_WINDOW_MS =
+            "persist.device_config.configuration.mitigation_window_ms";
+    @VisibleForTesting
+    static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5);
+
     // Threshold level at which or above user might experience significant disruption.
     private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
             "persist.device_config.configuration.major_user_impact_level_threshold";
@@ -210,6 +216,9 @@
     @GuardedBy("mLock")
     private boolean mSyncRequired = false;
 
+    @GuardedBy("mLock")
+    private long mLastMitigation = -1000000;
+
     @FunctionalInterface
     @VisibleForTesting
     interface SystemClock {
@@ -400,6 +409,16 @@
             Slog.w(TAG, "Could not resolve a list of failing packages");
             return;
         }
+        synchronized (mLock) {
+            final long now = mSystemClock.uptimeMillis();
+            if (Flags.recoverabilityDetection()) {
+                if (now >= mLastMitigation
+                        && (now - mLastMitigation) < getMitigationWindowMs()) {
+                    Slog.i(TAG, "Skipping onPackageFailure mitigation");
+                    return;
+                }
+            }
+        }
         mLongTaskHandler.post(() -> {
             synchronized (mLock) {
                 if (mAllObservers.isEmpty()) {
@@ -500,10 +519,17 @@
                               int currentObserverImpact,
                               int mitigationCount) {
         if (currentObserverImpact < getUserImpactLevelLimit()) {
+            synchronized (mLock) {
+                mLastMitigation = mSystemClock.uptimeMillis();
+            }
             currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount);
         }
     }
 
+    private long getMitigationWindowMs() {
+        return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS);
+    }
+
 
     /**
      * Called when the system server boots. If the system server is detected to be in a boot loop,
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index c5c2b0b..a19bb1d 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -885,6 +885,7 @@
             }
             synchronized (this) {
                 pinnedApp.mFiles.add(pf);
+                mPinnedFiles.put(pf.fileName, pf);
             }
 
             apkPinSizeLimit -= pf.bytesPinned;
@@ -1356,18 +1357,6 @@
 
     public List<PinnedFileStat> getPinnerStats() {
         ArrayList<PinnedFileStat> stats = new ArrayList<>();
-        Collection<PinnedApp> pinnedApps;
-        synchronized(this) {
-            pinnedApps = mPinnedApps.values();
-        }
-        for (PinnedApp pinnedApp : pinnedApps) {
-            for (PinnedFile pf : pinnedApp.mFiles) {
-                PinnedFileStat stat =
-                        new PinnedFileStat(pf.fileName, pf.bytesPinned, pf.groupName);
-                stats.add(stat);
-            }
-        }
-
         Collection<PinnedFile> pinnedFiles;
         synchronized(this) {
             pinnedFiles = mPinnedFiles.values();
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 79620cf..1c1190f 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1638,7 +1638,13 @@
                 String gidStr = parser.getAttributeValue(null, "gid");
                 if (gidStr != null) {
                     int gid = Process.getGidForName(gidStr);
-                    perm.gids = appendInt(perm.gids, gid);
+                    if (gid != -1) {
+                        perm.gids = appendInt(perm.gids, gid);
+                    } else {
+                        Slog.w(TAG, "<group> with unknown gid \""
+                                + gidStr + " for permission " + name + " in "
+                                + parser.getPositionDescription());
+                    }
                 } else {
                     Slog.w(TAG, "<group> without gid at "
                             + parser.getPositionDescription());
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 7acca19..e2b6bd6 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -36,6 +36,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -47,6 +48,7 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.vcn.Flags;
 import android.net.vcn.IVcnManagementService;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -68,6 +70,7 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -431,6 +434,8 @@
         mTelephonySubscriptionTracker.register();
     }
 
+    // The system server automatically has the required permissions for #getMainUser()
+    @SuppressLint("AndroidFrameworkRequiresPermission")
     private void enforcePrimaryUser() {
         final int uid = mDeps.getBinderCallingUid();
         if (uid == Process.SYSTEM_UID) {
@@ -438,7 +443,20 @@
                     "Calling identity was System Server. Was Binder calling identity cleared?");
         }
 
-        if (!UserHandle.getUserHandleForUid(uid).isSystem()) {
+        final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
+
+        if (Flags.enforceMainUser()) {
+            final UserManager userManager = mContext.getSystemService(UserManager.class);
+
+            Binder.withCleanCallingIdentity(
+                    () -> {
+                        if (!Objects.equals(userManager.getMainUser(), userHandle)) {
+                            throw new SecurityException(
+                                    "VcnManagementService can only be used by callers running as"
+                                            + " the main user");
+                        }
+                    });
+        } else if (!userHandle.isSystem()) {
             throw new SecurityException(
                     "VcnManagementService can only be used by callers running as the primary user");
         }
diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
index 2812233..42391a5 100644
--- a/services/core/java/com/android/server/WallpaperUpdateReceiver.java
+++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
@@ -24,7 +24,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Bitmap;
 import android.os.AsyncTask;
 import android.os.ParcelFileDescriptor;
 import android.util.Slog;
@@ -59,10 +58,10 @@
                 return;
             }
             if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper.");
-            Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
-            // set a blank wallpaper to force a redraw of default_wallpaper
-            wallpaperManager.setBitmap(blank);
-            wallpaperManager.setResource(com.android.internal.R.drawable.default_wallpaper);
+            // Check if it is not a live wallpaper set
+            if (wallpaperManager.getWallpaperInfo() == null) {
+                wallpaperManager.clearWallpaper();
+            }
         } catch (Exception e) {
             Slog.w(TAG, "Failed to customize system wallpaper." + e);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 28d840b..11e4a03 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -369,6 +369,8 @@
 import android.provider.Settings;
 import android.server.ServerProtoEnums;
 import android.sysprop.InitProperties;
+import android.system.Os;
+import android.system.OsConstants;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
@@ -9618,6 +9620,13 @@
             sb.append("ErrorId: ").append(errorId.toString()).append("\n");
         }
         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+
+        // If device is not using 4KB pages, add the PageSize
+        long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+        if (pageSize != 4096) {
+            sb.append("PageSize: ").append(pageSize).append("\n");
+        }
+
         if (Debug.isDebuggerConnected()) {
             sb.append("Debugger: Connected\n");
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index c13f02e..9a17366 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -127,6 +127,7 @@
 import com.android.server.am.nano.Capability;
 import com.android.server.am.nano.FrameworkCapability;
 import com.android.server.am.nano.VMCapability;
+import com.android.server.am.nano.VMInfo;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.utils.Slogf;
@@ -438,6 +439,8 @@
                 return -1;
             }
         }
+        String vmName = System.getProperty("java.vm.name", "?");
+        String vmVersion = System.getProperty("java.vm.version", "?");
 
         if (outputAsProtobuf) {
             Capabilities capabilities = new Capabilities();
@@ -464,6 +467,11 @@
                 capabilities.frameworkCapabilities[i] = cap;
             }
 
+            VMInfo vmInfo = new VMInfo();
+            vmInfo.name = vmName;
+            vmInfo.version = vmVersion;
+            capabilities.vmInfo = vmInfo;
+
             try {
                 getRawOutputStream().write(Capabilities.toByteArray(capabilities));
             } catch (IOException e) {
@@ -483,6 +491,8 @@
             for (String capability : Debug.getFeatureList()) {
                 pw.println("framework:" + capability);
             }
+            pw.println("vm_name:" + vmName);
+            pw.println("vm_version:" + vmVersion);
         }
         return 0;
     }
diff --git a/services/core/java/com/android/server/am/Android.bp b/services/core/java/com/android/server/am/Android.bp
index af1200e..0294ffe 100644
--- a/services/core/java/com/android/server/am/Android.bp
+++ b/services/core/java/com/android/server/am/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "am_flags",
     package: "com.android.server.am",
+    container: "system",
     srcs: ["*.aconfig"],
 }
 
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index c666915..46e197e 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.am"
+container: "system"
 
 flag {
     name: "oomadjuster_correctness_rewrite"
diff --git a/services/core/java/com/android/server/app/flags.aconfig b/services/core/java/com/android/server/app/flags.aconfig
index f2e4783..a5a68de 100644
--- a/services/core/java/com/android/server/app/flags.aconfig
+++ b/services/core/java/com/android/server/app/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.server.app"
+container: "system"
 
 flag {
     name: "game_default_frame_rate"
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5e6cf1a..69c6752 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4408,7 +4408,8 @@
                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
                 voiceActive = true;
             }
-            if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) {
+            if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME
+                    || usage == AudioAttributes.USAGE_UNKNOWN) {
                 mediaActive = true;
             }
         }
@@ -9680,9 +9681,9 @@
             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
             mContentResolver.registerContentObserver(Settings.System.getUriFor(
-                    Settings.System.MASTER_MONO), false, this);
+                    Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL);
             mContentResolver.registerContentObserver(Settings.System.getUriFor(
-                    Settings.System.MASTER_BALANCE), false, this);
+                    Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL);
 
             mEncodedSurroundMode = mSettings.getGlobalInt(
                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
diff --git a/services/core/java/com/android/server/audio/MusicFxHelper.java b/services/core/java/com/android/server/audio/MusicFxHelper.java
index 85b3b49..cf0b2ae 100644
--- a/services/core/java/com/android/server/audio/MusicFxHelper.java
+++ b/services/core/java/com/android/server/audio/MusicFxHelper.java
@@ -70,6 +70,8 @@
     // The binder token identifying the UidObserver registration.
     private IBinder mUidObserverToken = null;
 
+    private boolean mIsBound;
+
     // Package name and list of open audio sessions for this package
     private static class PackageSessions {
         String mPackageName;
@@ -90,7 +92,6 @@
      *    observer will also be removed, and observer token reset to null
      */
     private class MySparseArray extends SparseArray<PackageSessions> {
-        private final String mMusicFxPackageName = "com.android.musicfx";
 
         @RequiresPermission(anyOf = {
                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
@@ -110,6 +111,7 @@
                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
                     Intent bindIntent = new Intent().setClassName(mMusicFxPackageName,
                             "com.android.musicfx.KeepAliveService");
+                    mIsBound = true;
                     mContext.bindServiceAsUser(
                             bindIntent, mMusicFxBindConnection, Context.BIND_AUTO_CREATE,
                             UserHandle.of(getCurrentUserId()));
@@ -158,9 +160,12 @@
                     Log.e(TAG, "RemoteException with unregisterUidObserver: " + e);
                 }
                 mUidObserverToken = null;
-                mContext.unbindService(mMusicFxBindConnection);
-                Log.i(TAG, "last session closed, unregister UID observer, and unbind "
-                        + mMusicFxPackageName);
+                if (mIsBound) {
+                    mContext.unbindService(mMusicFxBindConnection);
+                    mIsBound = false;
+                    Log.i(TAG, "last session closed, unregister UID observer, and unbind "
+                            + mMusicFxPackageName);
+                }
             }
         }
     }
@@ -229,6 +234,10 @@
         if (ril != null && ril.size() != 0) {
             ResolveInfo ri = ril.get(0);
             final String senderPackageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME);
+            if (senderPackageName == null) {
+                Log.w(TAG, "Intent package name must not be null");
+                return;
+            }
             try {
                 if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
                     final int senderUid = pm.getPackageUidAsUser(senderPackageName,
@@ -265,7 +274,7 @@
                         + senderUid + ", package: " + senderPackageName + ", abort");
                 return false;
             }
-            if (pkgSessions.mPackageName != senderPackageName) {
+            if (!pkgSessions.mPackageName.equals(senderPackageName)) {
                 Log.w(TAG, "Inconsistency package names for UID open: " + senderUid + " prev: "
                         + pkgSessions.mPackageName + ", now: " + senderPackageName);
                 return false;
@@ -297,7 +306,7 @@
             Log.e(TAG, senderPackageName + " UID " + senderUid + " does not exist in map, abort");
             return false;
         }
-        if (pkgSessions.mPackageName != senderPackageName) {
+        if (!pkgSessions.mPackageName.equals(senderPackageName)) {
             Log.w(TAG, "Inconsistency package names for UID " + senderUid + " close, prev: "
                     + pkgSessions.mPackageName + ", now: " + senderPackageName);
             return false;
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 4f7f31d..5be2291 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -342,9 +342,6 @@
     //------------------------------------------------------
     // routing monitoring
     synchronized void onRoutingUpdated() {
-        if (!mFeatureEnabled) {
-            return;
-        }
         switch (mState) {
             case STATE_UNINITIALIZED:
             case STATE_NOT_SUPPORTED:
@@ -388,7 +385,7 @@
             setDispatchAvailableState(false);
         }
 
-        boolean enabled = able && enabledAvailable.first;
+        boolean enabled = mFeatureEnabled && able && enabledAvailable.first;
         if (enabled) {
             loglogi("Enabling Spatial Audio since enabled for media device:"
                     + currentDevice);
diff --git a/services/core/java/com/android/server/biometrics/Android.bp b/services/core/java/com/android/server/biometrics/Android.bp
index 6cbe4ad..ed5de030 100644
--- a/services/core/java/com/android/server/biometrics/Android.bp
+++ b/services/core/java/com/android/server/biometrics/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "biometrics_flags",
     package: "com.android.server.biometrics",
+    container: "system",
     srcs: [
         "biometrics.aconfig",
     ],
diff --git a/services/core/java/com/android/server/biometrics/biometrics.aconfig b/services/core/java/com/android/server/biometrics/biometrics.aconfig
index b12d831..7a9491e 100644
--- a/services/core/java/com/android/server/biometrics/biometrics.aconfig
+++ b/services/core/java/com/android/server/biometrics/biometrics.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.biometrics"
+container: "system"
 
 flag {
   name: "face_vhal_feature"
diff --git a/services/core/java/com/android/server/connectivity/Android.bp b/services/core/java/com/android/server/connectivity/Android.bp
index a374ec2..0916594 100644
--- a/services/core/java/com/android/server/connectivity/Android.bp
+++ b/services/core/java/com/android/server/connectivity/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "connectivity_flags",
     package: "com.android.server.connectivity",
+    container: "system",
     srcs: ["flags.aconfig"],
 }
 
diff --git a/services/core/java/com/android/server/connectivity/flags.aconfig b/services/core/java/com/android/server/connectivity/flags.aconfig
index 32593d4..bc240d4 100644
--- a/services/core/java/com/android/server/connectivity/flags.aconfig
+++ b/services/core/java/com/android/server/connectivity/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.connectivity"
+container: "system"
 
 flag {
     name: "replace_vpn_profile_store"
diff --git a/services/core/java/com/android/server/display/feature/Android.bp b/services/core/java/com/android/server/display/feature/Android.bp
index a0ead38..daf8832 100644
--- a/services/core/java/com/android/server/display/feature/Android.bp
+++ b/services/core/java/com/android/server/display/feature/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "display_flags",
     package: "com.android.server.display.feature.flags",
+    container: "system",
     srcs: [
         "*.aconfig",
     ],
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 7a723a3..de67702 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.display.feature.flags"
+container: "system"
 
 # Important: Flags must be accessed through DisplayManagerFlags.
 
diff --git a/services/core/java/com/android/server/feature/Android.bp b/services/core/java/com/android/server/feature/Android.bp
index 067288d..b0fbab6 100644
--- a/services/core/java/com/android/server/feature/Android.bp
+++ b/services/core/java/com/android/server/feature/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "dropbox_flags",
     package: "com.android.server.feature.flags",
+    container: "system",
     srcs: [
         "dropbox_flags.aconfig",
     ],
diff --git a/services/core/java/com/android/server/feature/dropbox_flags.aconfig b/services/core/java/com/android/server/feature/dropbox_flags.aconfig
index fee4bf3..b43d35a 100644
--- a/services/core/java/com/android/server/feature/dropbox_flags.aconfig
+++ b/services/core/java/com/android/server/feature/dropbox_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.feature.flags"
+container: "system"
 
 flag{
     name: "enable_read_dropbox_permission"
diff --git a/services/core/java/com/android/server/flags/pinner.aconfig b/services/core/java/com/android/server/flags/pinner.aconfig
index 606a6be..16a45cd 100644
--- a/services/core/java/com/android/server/flags/pinner.aconfig
+++ b/services/core/java/com/android/server/flags/pinner.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.flags"
+container: "system"
 
 flag {
     name: "pin_webview"
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 9087354..3f89f23 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -347,7 +347,7 @@
      * {@link HdmiCecNetwork} only.
      *
      * @return CEC physical address of the device. The range of success address
-     *         is between 0x0000 and 0xFFFF. If failed it returns -1
+     *         is between 0x0000 and 0xFFFE. If failed it returns INVALID_PHYSICAL_ADDRESS.
      */
     @ServiceThreadOnly
     int getPhysicalAddress() {
@@ -1299,7 +1299,7 @@
                     hdmiPortInfo[i] = new HdmiPortInfo.Builder(
                             portInfo.portId,
                             portInfo.type,
-                            portInfo.physicalAddress)
+                            Short.toUnsignedInt(portInfo.physicalAddress))
                             .setCecSupported(portInfo.cecSupported)
                             .setMhlSupported(false)
                             .setArcSupported(portInfo.arcSupported)
@@ -1496,7 +1496,7 @@
                     hdmiPortInfo[i] = new HdmiPortInfo.Builder(
                             portInfo.portId,
                             portInfo.type,
-                            portInfo.physicalAddress)
+                            Short.toUnsignedInt(portInfo.physicalAddress))
                             .setCecSupported(portInfo.cecSupported)
                             .setMhlSupported(false)
                             .setArcSupported(portInfo.arcSupported)
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
index 8949427..bf6633e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlShellCommand.java
@@ -124,8 +124,7 @@
                 return historySize(pw);
         }
 
-        getErrPrintWriter().println("Unhandled command: " + cmd);
-        return 1;
+        return handleDefaultCommands(cmd);
     }
 
     private int deviceSelect(PrintWriter pw) throws RemoteException {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ba99d2e..54fb65c4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -724,12 +724,13 @@
                     !mUserManager.isQuietModeEnabled(userHandle)) {
                 // Only show notifications for managed profiles once their parent
                 // user is unlocked.
-                showEncryptionNotificationForProfile(userHandle, reason);
+                showEncryptionNotificationForProfile(userHandle, parent.getUserHandle(), reason);
             }
         }
     }
 
-    private void showEncryptionNotificationForProfile(UserHandle user, String reason) {
+    private void showEncryptionNotificationForProfile(UserHandle user, UserHandle parent,
+            String reason) {
         CharSequence title = getEncryptionNotificationTitle();
         CharSequence message = getEncryptionNotificationMessage();
         CharSequence detail = getEncryptionNotificationDetail();
@@ -746,8 +747,15 @@
 
         unlockIntent.setFlags(
                 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
+        PendingIntent intent;
+        if (android.app.admin.flags.Flags.hsumUnlockNotificationFix()) {
+            intent = PendingIntent.getActivityAsUser(mContext, 0, unlockIntent,
+                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED,
+                    null, parent);
+        } else {
+            intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
+        }
 
         Slogf.d(TAG, "Showing encryption notification for user %d; reason: %s",
                 user.getIdentifier(), reason);
diff --git a/services/core/java/com/android/server/net/Android.bp b/services/core/java/com/android/server/net/Android.bp
index 71d8e6b..3ac2d23 100644
--- a/services/core/java/com/android/server/net/Android.bp
+++ b/services/core/java/com/android/server/net/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "net_flags",
     package: "com.android.server.net",
+    container: "system",
     srcs: ["*.aconfig"],
 }
 
diff --git a/services/core/java/com/android/server/net/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java
index d25f529..5ea3e70 100644
--- a/services/core/java/com/android/server/net/NetworkManagementService.java
+++ b/services/core/java/com/android/server/net/NetworkManagementService.java
@@ -20,6 +20,9 @@
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -31,6 +34,9 @@
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
@@ -143,6 +149,8 @@
     private final Object mQuotaLock = new Object();
     private final Object mRulesLock = new Object();
 
+    private final boolean mUseMeteredFirewallChains;
+
     /** Set of interfaces with active quotas. */
     @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
@@ -150,9 +158,11 @@
     @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
     /** Set of UIDs denied on metered networks. */
+    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
     @GuardedBy("mRulesLock")
     private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
     /** Set of UIDs allowed on metered networks. */
+    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
     @GuardedBy("mRulesLock")
     private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
     /** Set of UIDs with cleartext penalties. */
@@ -196,10 +206,32 @@
     @GuardedBy("mRulesLock")
     private final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray();
 
+    /**
+     * Contains the per-UID firewall rules that are used to allowlist the app from metered-network
+     * restrictions when data saver is enabled.
+     */
+    @GuardedBy("mRulesLock")
+    private final SparseIntArray mUidMeteredFirewallAllowRules = new SparseIntArray();
+
+    /**
+     * Contains the per-UID firewall rules that are used to deny app access to metered networks
+     * due to user action.
+     */
+    @GuardedBy("mRulesLock")
+    private final SparseIntArray mUidMeteredFirewallDenyUserRules = new SparseIntArray();
+
+    /**
+     * Contains the per-UID firewall rules that are used to deny app access to metered networks
+     * due to admin action.
+     */
+    @GuardedBy("mRulesLock")
+    private final SparseIntArray mUidMeteredFirewallDenyAdminRules = new SparseIntArray();
+
     /** Set of states for the child firewall chains. True if the chain is active. */
     @GuardedBy("mRulesLock")
     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
 
+    // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains.
     @GuardedBy("mQuotaLock")
     private volatile boolean mDataSaverMode;
 
@@ -217,6 +249,15 @@
         mContext = context;
         mDeps = deps;
 
+        mUseMeteredFirewallChains = Flags.useMeteredFirewallChains();
+
+        if (mUseMeteredFirewallChains) {
+            // These firewalls are always on and currently ConnectivityService does not allow
+            // changing their enabled state.
+            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_USER, true);
+            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_ADMIN, true);
+        }
+
         mDaemonHandler = new Handler(FgThread.get().getLooper());
 
         mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
@@ -410,33 +451,39 @@
                 }
             }
 
-            SparseBooleanArray uidRejectOnQuota = null;
-            SparseBooleanArray uidAcceptOnQuota = null;
-            synchronized (mRulesLock) {
-                size = mUidRejectOnMetered.size();
-                if (size > 0) {
-                    if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules");
-                    uidRejectOnQuota = mUidRejectOnMetered;
-                    mUidRejectOnMetered = new SparseBooleanArray();
-                }
+            if (!mUseMeteredFirewallChains) {
+                SparseBooleanArray uidRejectOnQuota = null;
+                SparseBooleanArray uidAcceptOnQuota = null;
+                synchronized (mRulesLock) {
+                    size = mUidRejectOnMetered.size();
+                    if (size > 0) {
+                        if (DBG) {
+                            Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules");
+                        }
+                        uidRejectOnQuota = mUidRejectOnMetered;
+                        mUidRejectOnMetered = new SparseBooleanArray();
+                    }
 
-                size = mUidAllowOnMetered.size();
-                if (size > 0) {
-                    if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules");
-                    uidAcceptOnQuota = mUidAllowOnMetered;
-                    mUidAllowOnMetered = new SparseBooleanArray();
+                    size = mUidAllowOnMetered.size();
+                    if (size > 0) {
+                        if (DBG) {
+                            Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules");
+                        }
+                        uidAcceptOnQuota = mUidAllowOnMetered;
+                        mUidAllowOnMetered = new SparseBooleanArray();
+                    }
                 }
-            }
-            if (uidRejectOnQuota != null) {
-                for (int i = 0; i < uidRejectOnQuota.size(); i++) {
-                    setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i),
-                            uidRejectOnQuota.valueAt(i));
+                if (uidRejectOnQuota != null) {
+                    for (int i = 0; i < uidRejectOnQuota.size(); i++) {
+                        setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i),
+                                uidRejectOnQuota.valueAt(i));
+                    }
                 }
-            }
-            if (uidAcceptOnQuota != null) {
-                for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
-                    setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i),
-                            uidAcceptOnQuota.valueAt(i));
+                if (uidAcceptOnQuota != null) {
+                    for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
+                        setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i),
+                                uidAcceptOnQuota.valueAt(i));
+                    }
                 }
             }
 
@@ -459,8 +506,16 @@
             syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted ");
             syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby ");
             syncFirewallChainLocked(FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_NAME_BACKGROUND);
+            if (mUseMeteredFirewallChains) {
+                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_ALLOW,
+                        FIREWALL_CHAIN_NAME_METERED_ALLOW);
+                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_USER,
+                        FIREWALL_CHAIN_NAME_METERED_DENY_USER);
+                syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_ADMIN,
+                        FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN);
+            }
 
-            final int[] chains = {
+            final int[] chainsToEnable = {
                     FIREWALL_CHAIN_STANDBY,
                     FIREWALL_CHAIN_DOZABLE,
                     FIREWALL_CHAIN_POWERSAVE,
@@ -469,14 +524,13 @@
                     FIREWALL_CHAIN_BACKGROUND,
             };
 
-            for (int chain : chains) {
+            for (int chain : chainsToEnable) {
                 if (getFirewallChainState(chain)) {
                     setFirewallChainEnabled(chain, true);
                 }
             }
         }
 
-
         try {
             getBatteryStats().noteNetworkStatsEnabled();
         } catch (RemoteException e) {
@@ -1077,6 +1131,14 @@
                     mContext.getSystemService(ConnectivityManager.class)
                             .setDataSaverEnabled(enable);
                     mDataSaverMode = enable;
+                    if (mUseMeteredFirewallChains) {
+                        // Copy mDataSaverMode state to FIREWALL_CHAIN_METERED_ALLOW
+                        // until ConnectivityService allows manipulation of the data saver mode via
+                        // FIREWALL_CHAIN_METERED_ALLOW.
+                        synchronized (mRulesLock) {
+                            mFirewallChainStates.put(FIREWALL_CHAIN_METERED_ALLOW, enable);
+                        }
+                    }
                     return true;
                 } else {
                     final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
@@ -1191,9 +1253,9 @@
                 setFirewallChainState(chain, enable);
             }
 
-            final String chainName = getFirewallChainName(chain);
-            if (chain == FIREWALL_CHAIN_NONE) {
-                throw new IllegalArgumentException("Bad child chain: " + chainName);
+            if (!isValidFirewallChainForSetEnabled(chain)) {
+                throw new IllegalArgumentException("Invalid chain for setFirewallChainEnabled: "
+                        + NetworkPolicyLogger.getFirewallChainName(chain));
             }
 
             final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
@@ -1205,38 +1267,29 @@
         }
     }
 
-    private String getFirewallChainName(int chain) {
-        switch (chain) {
-            case FIREWALL_CHAIN_STANDBY:
-                return FIREWALL_CHAIN_NAME_STANDBY;
-            case FIREWALL_CHAIN_DOZABLE:
-                return FIREWALL_CHAIN_NAME_DOZABLE;
-            case FIREWALL_CHAIN_POWERSAVE:
-                return FIREWALL_CHAIN_NAME_POWERSAVE;
-            case FIREWALL_CHAIN_RESTRICTED:
-                return FIREWALL_CHAIN_NAME_RESTRICTED;
-            case FIREWALL_CHAIN_LOW_POWER_STANDBY:
-                return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
-            case FIREWALL_CHAIN_BACKGROUND:
-                return FIREWALL_CHAIN_NAME_BACKGROUND;
-            default:
-                throw new IllegalArgumentException("Bad child chain: " + chain);
-        }
+    private boolean isValidFirewallChainForSetEnabled(int chain) {
+        return switch (chain) {
+            case FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE,
+                    FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY,
+                    FIREWALL_CHAIN_BACKGROUND -> true;
+            // METERED_* firewall chains are not yet supported by
+            // ConnectivityService#setFirewallChainEnabled.
+            default -> false;
+        };
     }
 
     private int getFirewallType(int chain) {
         switch (chain) {
             case FIREWALL_CHAIN_STANDBY:
+            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
+            case FIREWALL_CHAIN_METERED_DENY_USER:
                 return FIREWALL_DENYLIST;
             case FIREWALL_CHAIN_DOZABLE:
-                return FIREWALL_ALLOWLIST;
             case FIREWALL_CHAIN_POWERSAVE:
-                return FIREWALL_ALLOWLIST;
             case FIREWALL_CHAIN_RESTRICTED:
-                return FIREWALL_ALLOWLIST;
             case FIREWALL_CHAIN_LOW_POWER_STANDBY:
-                return FIREWALL_ALLOWLIST;
             case FIREWALL_CHAIN_BACKGROUND:
+            case FIREWALL_CHAIN_METERED_ALLOW:
                 return FIREWALL_ALLOWLIST;
             default:
                 return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
@@ -1360,6 +1413,12 @@
                 return mUidFirewallLowPowerStandbyRules;
             case FIREWALL_CHAIN_BACKGROUND:
                 return mUidFirewallBackgroundRules;
+            case FIREWALL_CHAIN_METERED_ALLOW:
+                return mUidMeteredFirewallAllowRules;
+            case FIREWALL_CHAIN_METERED_DENY_USER:
+                return mUidMeteredFirewallDenyUserRules;
+            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
+                return mUidMeteredFirewallDenyAdminRules;
             case FIREWALL_CHAIN_NONE:
                 return mUidFirewallRules;
             default:
@@ -1378,6 +1437,10 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
+        pw.println("Flags:");
+        pw.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": " + mUseMeteredFirewallChains);
+        pw.println();
+
         synchronized (mQuotaLock) {
             pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
             pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
@@ -1416,6 +1479,27 @@
             pw.print("UID firewall background chain enabled: ");
             pw.println(getFirewallChainState(FIREWALL_CHAIN_BACKGROUND));
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_BACKGROUND, mUidFirewallBackgroundRules);
+
+            pw.print("UID firewall metered allow chain enabled (Data saver mode): ");
+            // getFirewallChainState should maintain a duplicated state from mDataSaverMode when
+            // mUseMeteredFirewallChains is enabled.
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW));
+            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_ALLOW,
+                    mUidMeteredFirewallAllowRules);
+
+            pw.print("UID firewall metered deny_user chain enabled (always-on): ");
+            // This always-on state should be reflected by getFirewallChainState when
+            // mUseMeteredFirewallChains is enabled.
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER));
+            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_USER,
+                    mUidMeteredFirewallDenyUserRules);
+
+            pw.print("UID firewall metered deny_admin chain enabled (always-on): ");
+            // This always-on state should be reflected by getFirewallChainState when
+            // mUseMeteredFirewallChains is enabled.
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN));
+            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN,
+                    mUidMeteredFirewallDenyAdminRules);
         }
 
         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
@@ -1520,14 +1604,40 @@
                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because it is in background");
                 return true;
             }
-            if (mUidRejectOnMetered.get(uid)) {
-                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
-                        + " in the background");
-                return true;
-            }
-            if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
-                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
-                return true;
+            if (mUseMeteredFirewallChains) {
+                if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER)
+                        && mUidMeteredFirewallDenyUserRules.get(uid) == FIREWALL_RULE_DENY) {
+                    if (DBG) {
+                        Slog.d(TAG, "Uid " + uid + " restricted because of user-restricted metered"
+                                + " data in the background");
+                    }
+                    return true;
+                }
+                if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN)
+                        && mUidMeteredFirewallDenyAdminRules.get(uid) == FIREWALL_RULE_DENY) {
+                    if (DBG) {
+                        Slog.d(TAG, "Uid " + uid + " restricted because of admin-restricted metered"
+                                + " data in the background");
+                    }
+                    return true;
+                }
+                if (getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW)
+                        && mUidMeteredFirewallAllowRules.get(uid) != FIREWALL_RULE_ALLOW) {
+                    if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
+                    return true;
+                }
+            } else {
+                if (mUidRejectOnMetered.get(uid)) {
+                    if (DBG) {
+                        Slog.d(TAG, "Uid " + uid
+                                + " restricted because of no metered data in the background");
+                    }
+                    return true;
+                }
+                if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
+                    if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
+                    return true;
+                }
             }
             return false;
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 8e2d778..681aa8a 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -19,6 +19,9 @@
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -28,6 +31,9 @@
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
@@ -379,7 +385,7 @@
         return "Interfaces of netId=" + netId + " changed to " + newIfaces;
     }
 
-    private static String getFirewallChainName(int chain) {
+    static String getFirewallChainName(int chain) {
         switch (chain) {
             case FIREWALL_CHAIN_DOZABLE:
                 return FIREWALL_CHAIN_NAME_DOZABLE;
@@ -393,6 +399,12 @@
                 return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
             case FIREWALL_CHAIN_BACKGROUND:
                 return FIREWALL_CHAIN_NAME_BACKGROUND;
+            case FIREWALL_CHAIN_METERED_ALLOW:
+                return FIREWALL_CHAIN_NAME_METERED_ALLOW;
+            case FIREWALL_CHAIN_METERED_DENY_USER:
+                return FIREWALL_CHAIN_NAME_METERED_DENY_USER;
+            case FIREWALL_CHAIN_METERED_DENY_ADMIN:
+                return FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN;
             default:
                 return String.valueOf(chain);
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c6fca9b..a26ac61 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -60,6 +60,9 @@
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
@@ -514,6 +517,12 @@
      */
     private boolean mBackgroundNetworkRestricted;
 
+    /**
+     * Whether or not metered firewall chains should be used for uid policy controlling access to
+     * metered networks.
+     */
+    private boolean mUseMeteredFirewallChains;
+
     // See main javadoc for instructions on how to use these locks.
     final Object mUidRulesFirstLock = new Object();
     final Object mNetworkPoliciesSecondLock = new Object();
@@ -997,6 +1006,8 @@
             mAppStandby = LocalServices.getService(AppStandbyInternal.class);
             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
 
+            mUseMeteredFirewallChains = Flags.useMeteredFirewallChains();
+
             synchronized (mUidRulesFirstLock) {
                 synchronized (mNetworkPoliciesSecondLock) {
                     updatePowerSaveAllowlistUL();
@@ -4030,8 +4041,10 @@
 
                 fout.println();
                 fout.println("Flags:");
-                fout.println("Network blocked for TOP_SLEEPING and above: "
+                fout.println(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE + ": "
                         + mBackgroundNetworkRestricted);
+                fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": "
+                        + mUseMeteredFirewallChains);
 
                 fout.println();
                 fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode);
@@ -5367,23 +5380,44 @@
             postUidRulesChangedMsg(uid, uidRules);
         }
 
-        // Note that the conditionals below are for avoiding unnecessary calls to netd.
-        // TODO: Measure the performance for doing a no-op call to netd so that we can
-        // remove the conditionals to simplify the logic below. We can also further reduce
-        // some calls to netd if they turn out to be costly.
-        final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED
-                | BLOCKED_METERED_REASON_USER_RESTRICTED;
-        if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE
-                || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) {
-            setMeteredNetworkDenylist(uid,
-                    (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE);
-        }
-        final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND
-                | ALLOWED_METERED_REASON_USER_EXEMPTED;
-        if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE
-                || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) {
-            setMeteredNetworkAllowlist(uid,
-                    (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE);
+        if (mUseMeteredFirewallChains) {
+            if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_ADMIN_DISABLED)
+                    != BLOCKED_REASON_NONE) {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DENY);
+            } else {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DEFAULT);
+            }
+            if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_USER_RESTRICTED)
+                    != BLOCKED_REASON_NONE) {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DENY);
+            } else {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DEFAULT);
+            }
+            if ((newAllowedReasons & (ALLOWED_METERED_REASON_FOREGROUND
+                    | ALLOWED_METERED_REASON_USER_EXEMPTED)) != ALLOWED_REASON_NONE) {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_ALLOW);
+            } else {
+                setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_DEFAULT);
+            }
+        } else {
+            // Note that the conditionals below are for avoiding unnecessary calls to netd.
+            // TODO: Measure the performance for doing a no-op call to netd so that we can
+            // remove the conditionals to simplify the logic below. We can also further reduce
+            // some calls to netd if they turn out to be costly.
+            final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED
+                    | BLOCKED_METERED_REASON_USER_RESTRICTED;
+            if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE
+                    || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) {
+                setMeteredNetworkDenylist(uid,
+                        (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE);
+            }
+            final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND
+                    | ALLOWED_METERED_REASON_USER_EXEMPTED;
+            if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE
+                    || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) {
+                setMeteredNetworkAllowlist(uid,
+                        (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE);
+            }
         }
     }
 
@@ -6143,6 +6177,8 @@
             } else if (chain == FIREWALL_CHAIN_BACKGROUND) {
                 mUidFirewallBackgroundRules.put(uid, rule);
             }
+            // Note that we do not need keep a separate cache of uid rules for chains that we do
+            // not call #setUidFirewallRulesUL for.
 
             try {
                 mNetworkManager.setFirewallUidRule(chain, uid, rule);
@@ -6200,10 +6236,19 @@
                     FIREWALL_RULE_DEFAULT);
             mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, uid,
                     FIREWALL_RULE_DEFAULT);
-            mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
-            mLogger.meteredAllowlistChanged(uid, false);
-            mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
-            mLogger.meteredDenylistChanged(uid, false);
+            if (mUseMeteredFirewallChains) {
+                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid,
+                        FIREWALL_RULE_DEFAULT);
+                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, uid,
+                        FIREWALL_RULE_DEFAULT);
+                mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, uid,
+                        FIREWALL_RULE_DEFAULT);
+            } else {
+                mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
+                mLogger.meteredAllowlistChanged(uid, false);
+                mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
+                mLogger.meteredDenylistChanged(uid, false);
+            }
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig
index 419665a..e986dd8 100644
--- a/services/core/java/com/android/server/net/flags.aconfig
+++ b/services/core/java/com/android/server/net/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.net"
+container: "system"
 
 flag {
     name: "network_blocked_for_top_sleeping_and_above"
@@ -6,3 +7,13 @@
     description: "Block network access for apps in a low importance background state"
     bug: "304347838"
 }
+
+flag {
+    name: "use_metered_firewall_chains"
+    namespace: "backstage_power"
+    description: "Use metered firewall chains to control access to metered networks"
+    bug: "336693007"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/services/core/java/com/android/server/notification/Android.bp b/services/core/java/com/android/server/notification/Android.bp
index f26a25b..9512418 100644
--- a/services/core/java/com/android/server/notification/Android.bp
+++ b/services/core/java/com/android/server/notification/Android.bp
@@ -6,7 +6,8 @@
 aconfig_declarations {
     name: "notification_flags",
     package: "com.android.server.notification",
+    container: "system",
     srcs: [
         "flags.aconfig",
     ],
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index dc0cf4e..017a96e 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -66,7 +66,7 @@
             + "  disallow_listener COMPONENT [user_id (current user if not specified)]\n"
             + "  allow_assistant COMPONENT [user_id (current user if not specified)]\n"
             + "  remove_assistant COMPONENT [user_id (current user if not specified)]\n"
-            + "  set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]"
+            + "  set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]\n"
             + "  allow_dnd PACKAGE [user_id (current user if not specified)]\n"
             + "  disallow_dnd PACKAGE [user_id (current user if not specified)]\n"
             + "  reset_assistant_user_set [user_id (current user if not specified)]\n"
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index da01745..efc9d9f 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.notification"
+container: "system"
 
 flag {
   name: "expire_bitmaps"
diff --git a/services/core/java/com/android/server/os/Android.bp b/services/core/java/com/android/server/os/Android.bp
index 565dc3b..c588670 100644
--- a/services/core/java/com/android/server/os/Android.bp
+++ b/services/core/java/com/android/server/os/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "core_os_flags",
     package: "com.android.server.os",
+    container: "system",
     srcs: [
         "*.aconfig",
     ],
diff --git a/services/core/java/com/android/server/os/core_os_flags.aconfig b/services/core/java/com/android/server/os/core_os_flags.aconfig
index cbc0d54..ae33df8 100644
--- a/services/core/java/com/android/server/os/core_os_flags.aconfig
+++ b/services/core/java/com/android/server/os/core_os_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.os"
+container: "system"
 
 flag {
     name: "proto_tombstone"
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 79d1753..348452e 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -534,9 +534,12 @@
         } else {
             storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
         }
-        List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
-                UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
-                true /* onlyCoreApps */);
+        final List<String> deferPackages;
+        synchronized (mPm.mInstallLock) {
+           deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
+                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
+                    true /* onlyCoreApps */);
+        }
         Future<?> prepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
             TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
                     Trace.TRACE_TAG_PACKAGE_MANAGER);
diff --git a/services/core/java/com/android/server/power/Android.bp b/services/core/java/com/android/server/power/Android.bp
index 607d435..46f03f2 100644
--- a/services/core/java/com/android/server/power/Android.bp
+++ b/services/core/java/com/android/server/power/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "backstage_power_flags",
     package: "com.android.server.power.optimization",
+    container: "system",
     srcs: [
         "stats/*.aconfig",
     ],
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 4eea8c6..8b286ad 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -3377,7 +3377,7 @@
             }
             return mTotalTimeUs + (mNesting > 0
                     ? (curBatteryRealtimeUs - mUpdateTimeUs)
-                            / (mTimerPool != null ? mTimerPool.size() : 1)
+                            / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1)
                     : 0);
         }
 
diff --git a/services/core/java/com/android/server/power/stats/flags.aconfig b/services/core/java/com/android/server/power/stats/flags.aconfig
index 0f13571..4c54214 100644
--- a/services/core/java/com/android/server/power/stats/flags.aconfig
+++ b/services/core/java/com/android/server/power/stats/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.power.optimization"
+container: "system"
 
 flag {
     name: "power_monitor_api"
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 93f26ae..c85ceac 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -642,6 +642,8 @@
                         .getPackages()
                         .get(0)
                         .getVersionRolledBackFrom();
+        Slog.i(TAG, "Rolling back high impact rollback for package: "
+                + firstRollback.getPackageName());
         rollbackPackage(sortedHighImpactRollbacks.get(0), firstRollback, rollbackReason);
     }
 
diff --git a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
index 519c0ed..7fc0292 100644
--- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
+++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
@@ -293,6 +293,8 @@
                 return "REASON_APP_NOT_RESPONDING";
             case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT:
                 return "REASON_NATIVE_CRASH_DURING_BOOT";
+            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING:
+                return "REASON_BOOT_LOOP";
             default:
                 return "UNKNOWN";
         }
diff --git a/services/core/java/com/android/server/utils/Android.bp b/services/core/java/com/android/server/utils/Android.bp
index 3a334be..ffb9aec 100644
--- a/services/core/java/com/android/server/utils/Android.bp
+++ b/services/core/java/com/android/server/utils/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "com.android.server.utils-aconfig",
     package: "com.android.server.utils",
+    container: "system",
     srcs: ["*.aconfig"],
 }
 
diff --git a/services/core/java/com/android/server/utils/flags.aconfig b/services/core/java/com/android/server/utils/flags.aconfig
index 489e21a..0eb1510 100644
--- a/services/core/java/com/android/server/utils/flags.aconfig
+++ b/services/core/java/com/android/server/utils/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.utils"
+container: "system"
 
 flag {
      name: "anr_timer_service_enabled"
diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index 3619253..47425322 100644
--- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -115,6 +115,10 @@
     // validation failure.
     private static final int IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DEFAULT = 12;
 
+    /** Carriers can disable the detector by setting the threshold to -1 */
+    @VisibleForTesting(visibility = Visibility.PRIVATE)
+    static final int IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR = -1;
+
     private static final int POLL_IPSEC_STATE_INTERVAL_SECONDS_DEFAULT = 20;
 
     // By default, there's no maximum limit enforced
@@ -271,7 +275,10 @@
         // When multiple parallel inbound transforms are created, NetworkMetricMonitor will be
         // enabled on the last one as a sample
         mInboundTransform = inboundTransform;
-        start();
+
+        if (!Flags.allowDisableIpsecLossDetector() || canStart()) {
+            start();
+        }
     }
 
     @Override
@@ -284,6 +291,14 @@
             mPacketLossRatePercentThreshold = getPacketLossRatePercentThreshold(carrierConfig);
             mMaxSeqNumIncreasePerSecond = getMaxSeqNumIncreasePerSecond(carrierConfig);
         }
+
+        if (Flags.allowDisableIpsecLossDetector() && canStart() != isStarted()) {
+            if (canStart()) {
+                start();
+            } else {
+                stop();
+            }
+        }
     }
 
     @Override
@@ -298,6 +313,12 @@
         mHandler.postDelayed(new PollIpSecStateRunnable(), mCancellationToken, 0L);
     }
 
+    private boolean canStart() {
+        return mInboundTransform != null
+                && mPacketLossRatePercentThreshold
+                        != IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR;
+    }
+
     @Override
     protected void start() {
         super.start();
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 1485b96..231ca5a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -3436,7 +3436,8 @@
             }
             // System wallpaper does not support multiple displays, attach this display to
             // the fallback wallpaper.
-            if (mFallbackWallpaper != null) {
+            if (mFallbackWallpaper != null && mFallbackWallpaper
+                        .connection != null) {
                 final DisplayConnector connector = mFallbackWallpaper
                         .connection.getDisplayConnectorOrCreate(displayId);
                 if (connector == null) return;
diff --git a/services/core/java/com/android/server/webkit/flags.aconfig b/services/core/java/com/android/server/webkit/flags.aconfig
index 1411acc..3d30e74 100644
--- a/services/core/java/com/android/server/webkit/flags.aconfig
+++ b/services/core/java/com/android/server/webkit/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.webkit"
+container: "system"
 
 flag {
     name: "update_service_v2"
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4b0177a..f249cb0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2643,7 +2643,7 @@
         // If a target task is specified, try to reuse that one
         if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
             Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
-            if (launchTask != null) {
+            if (launchTask != null && launchTask.isLeafTask()) {
                 return launchTask;
             }
             return null;
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index ce47f5c..60454fc 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -18,6 +18,7 @@
 yunfanc@google.com
 wilsonshih@google.com
 jiamingliu@google.com
+pdwilliams@google.com
 
 # Files related to background activity launches
 per-file Background*Start* = set noparent
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dd49260..9dfca4d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -432,10 +432,10 @@
 import android.security.IKeyChainService;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
-import android.security.KeyStore;
 import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keystore.AttestationUtils;
 import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
 import android.security.keystore.ParcelableKeyGenParameterSpec;
 import android.stats.devicepolicy.DevicePolicyEnums;
 import android.telecom.TelecomManager;
@@ -6248,7 +6248,7 @@
                     KeyChain.bindAsUser(mContext, caller.getUserHandle());
             try {
                 IKeyChainService keyChain = keyChainConnection.getService();
-                if (!keyChain.installKeyPair(privKey, cert, chain, alias, KeyStore.UID_SELF)) {
+                if (!keyChain.installKeyPair(privKey, cert, chain, alias, KeyProperties.UID_SELF)) {
                     logInstallKeyPairFailure(caller, isCredentialManagementApp);
                     return false;
                 }
@@ -6588,7 +6588,7 @@
         }
         // As the caller will be granted access to the key, ensure no UID was specified, as
         // it will not have the desired effect.
-        if (keySpec.getUid() != KeyStore.UID_SELF) {
+        if (keySpec.getUid() != KeyProperties.UID_SELF) {
             Slogf.e(LOG_TAG, "Only the caller can be granted access to the generated keypair.");
             logGenerateKeyPairFailure(caller, isCredentialManagementApp);
             return false;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
index 0e448cd..a1bf040 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
@@ -25,7 +25,6 @@
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Awaits the deletion of all the non-required apps.
@@ -33,38 +32,38 @@
 final class NonRequiredPackageDeleteObserver extends IPackageDeleteObserver.Stub {
     private static final int PACKAGE_DELETE_TIMEOUT_SEC = 30;
 
-    private final AtomicInteger mPackageCount = new AtomicInteger(/* initialValue= */ 0);
     private final CountDownLatch mLatch;
-    private boolean mSuccess;
+    private boolean mFailed = false;
 
     NonRequiredPackageDeleteObserver(int packageCount) {
         this.mLatch = new CountDownLatch(packageCount);
-        this.mPackageCount.set(packageCount);
     }
 
     @Override
     public void packageDeleted(String packageName, int returnCode) {
         if (returnCode != PackageManager.DELETE_SUCCEEDED) {
             Slog.e(LOG_TAG, "Failed to delete package: " + packageName);
-            mLatch.notifyAll();
-            return;
-        }
-        int currentPackageCount = mPackageCount.decrementAndGet();
-        if (currentPackageCount == 0) {
-            mSuccess = true;
-            Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
-                    + "and all disallowed apps have been uninstalled.");
+            mFailed = true;
         }
         mLatch.countDown();
     }
 
     public boolean awaitPackagesDeletion() {
         try {
-            mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS);
+            if (mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                if (!mFailed) {
+                    Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
+                            + "and all disallowed apps have been uninstalled.");
+                }
+                return !mFailed;
+            } else {
+                Slog.i(LOG_TAG, "Waiting time elapsed before all package deletion finished");
+                return false;
+            }
         } catch (InterruptedException e) {
             Log.w(LOG_TAG, "Interrupted while waiting for package deletion", e);
             Thread.currentThread().interrupt();
+            return false;
         }
-        return mSuccess;
     }
 }
diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
index 6ad8d79..6393e11 100644
--- a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
+++ b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "device_state_flags",
     package: "com.android.server.policy.feature.flags",
+    container: "system",
     srcs: [
         "device_state_flags.aconfig",
     ],
diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
index 29e258c..21e33dd 100644
--- a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
+++ b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.policy.feature.flags"
+container: "system"
 
 flag {
     name: "enable_dual_display_blocking"
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index f469ab5..33d3cd0 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -2077,8 +2077,20 @@
                     writer.println("Unknown app ID $appId.")
                 }
             }
+        } else if (args[0] == "--package" && args.size == 2) {
+            val packageName = args[1]
+            service.getState {
+                val packageState = state.externalState.packageStates[packageName]
+                if (packageState != null) {
+                    writer.dumpAppIdState(packageState.appId, state, indexedSetOf(packageName))
+                } else {
+                    writer.println("Unknown package $packageName.")
+                }
+            }
         } else {
-            writer.println("Usage: dumpsys permission [--app-id APP_ID]")
+            writer.println(
+                "Usage: dumpsys permissionmgr [--app-id <APP_ID>] [--package <PACKAGE_NAME>]"
+            )
         }
     }
 
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 68038fa..9f97648 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -63,6 +63,9 @@
             "com.android.server.profcollect.UPLOAD_PROFILES";
     private static final long BG_PROCESS_INTERVAL = TimeUnit.HOURS.toMillis(4); // every 4 hours.
 
+    private int mUsageSetting;
+    private boolean mUploadEnabled;
+
     private IProfCollectd mIProfcollect;
     private static ProfcollectForwardingService sSelfService;
     private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
@@ -78,7 +81,7 @@
         public void onReceive(Context context, Intent intent) {
             if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) {
                 Log.d(LOG_TAG, "Received broadcast to pack and upload reports");
-                packAndUploadReport();
+                createAndUploadReport(sSelfService);
             }
         }
     };
@@ -91,6 +94,17 @@
         }
         sSelfService = this;
 
+        // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for disabled.
+        try {
+            mUsageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb");
+        } catch (SettingNotFoundException e) {
+            Log.e(LOG_TAG, "Usage setting not found: " + e.getMessage());
+            mUsageSetting = -1;
+        }
+
+        mUploadEnabled =
+            context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled);
+
         final IntentFilter filter = new IntentFilter();
         filter.addAction(INTENT_UPLOAD_PROFILES);
         context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
@@ -221,7 +235,6 @@
          */
         public static void schedule(Context context) {
             JobScheduler js = context.getSystemService(JobScheduler.class);
-
             js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME)
                     .setRequiresDeviceIdle(true)
                     .setRequiresCharging(true)
@@ -235,19 +248,8 @@
             if (DEBUG) {
                 Log.d(LOG_TAG, "Starting background process job");
             }
-
-            BackgroundThread.get().getThreadHandler().post(
-                    () -> {
-                        try {
-                            if (sSelfService.mIProfcollect == null) {
-                                return;
-                            }
-                            sSelfService.mIProfcollect.process();
-                        } catch (RemoteException e) {
-                            Log.e(LOG_TAG, "Failed to process profiles in background: "
-                                    + e.getMessage());
-                        }
-                    });
+            createAndUploadReport(sSelfService);
+            jobFinished(params, false);
             return true;
         }
 
@@ -356,7 +358,7 @@
                 }
 
                 if (status == UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT) {
-                    packAndUploadReport();
+                    createAndUploadReport(sSelfService);
                 }
             }
 
@@ -367,41 +369,27 @@
         });
     }
 
-    private void packAndUploadReport() {
-        if (mIProfcollect == null) {
-            return;
-        }
-
-        Context context = getContext();
+    private static void createAndUploadReport(ProfcollectForwardingService pfs) {
         BackgroundThread.get().getThreadHandler().post(() -> {
+            String reportName;
             try {
-                int usageSetting = -1;
-                try {
-                    // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for
-                    // disabled.
-                    usageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb");
-                } catch (SettingNotFoundException e) {
-                    Log.i(LOG_TAG, "Usage setting not found: " + e.getMessage());
-                }
-
-                // Prepare profile report
-                String reportName = mIProfcollect.report(usageSetting) + ".zip";
-
-                if (!context.getResources().getBoolean(
-                        R.bool.config_profcollectReportUploaderEnabled)) {
-                    Log.i(LOG_TAG, "Upload is not enabled.");
-                    return;
-                }
-
-                // Upload the report
-                Intent intent = new Intent()
-                        .setPackage("com.android.shell")
-                        .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
-                        .putExtra("filename", reportName);
-                context.sendBroadcast(intent);
+                reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip";
             } catch (RemoteException e) {
-                Log.e(LOG_TAG, "Failed to upload report: " + e.getMessage());
+                Log.e(LOG_TAG, "Failed to create report: " + e.getMessage());
+                return;
             }
+            if (!pfs.mUploadEnabled) {
+                Log.i(LOG_TAG, "Upload is not enabled.");
+                return;
+            }
+            Intent intent = new Intent()
+                    .setPackage("com.android.shell")
+                    .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
+                    .putExtra("filename", reportName);
+            pfs.getContext().sendBroadcast(intent);
         });
+        if (DEBUG) {
+            Log.d(LOG_TAG, "Sent report for upload.");
+        }
     }
 }
diff --git a/services/tests/apexsystemservices/OWNERS b/services/tests/apexsystemservices/OWNERS
index 0295b9e..8b6675a 100644
--- a/services/tests/apexsystemservices/OWNERS
+++ b/services/tests/apexsystemservices/OWNERS
@@ -1,4 +1 @@
-omakoto@google.com
-satayev@google.com
-
 include platform/packages/modules/common:/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 4a21645..42814e7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -239,6 +239,9 @@
 
     @Test
     public void testBootLoopDetectionWithExecutionForAllRescueLevels() {
+        // this is old test where the flag needs to be disabled
+        mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+
         RescueParty.onSettingsProviderPublished(mMockContext);
         verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
                 any(Executor.class),
@@ -449,6 +452,9 @@
 
     @Test
     public void testNonPersistentAppCrashDetectionWithScopedResets() {
+        // this is old test where the flag needs to be disabled
+        mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+
         RescueParty.onSettingsProviderPublished(mMockContext);
         verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
                 any(Executor.class),
@@ -506,6 +512,9 @@
 
     @Test
     public void testNonDeviceConfigSettingsOnlyResetOncePerLevel() {
+        // this is old test where the flag needs to be disabled
+        mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+
         RescueParty.onSettingsProviderPublished(mMockContext);
         verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
                 any(Executor.class),
@@ -879,6 +888,9 @@
 
     @Test
     public void testBootLoopLevels() {
+        // this is old test where the flag needs to be disabled
+        mSetFlagsRule.disableFlags(Flags.FLAG_RECOVERABILITY_DETECTION);
+
         RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
 
         assertEquals(observer.onBootLoop(0), PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
index 72c0a9e..2cbc226 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -1 +1,3 @@
 include /services/core/java/com/android/server/am/OWNERS
+
+per-file ApplicationStartInfoTest.java = yforta@google.com, carmenjackson@google.com, jji@google.com
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index b1d5039..84bafda 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -25,6 +25,13 @@
                 value="/data/local/tmp/cts/content/broken_shortcut.xml" />
     </target_preparer>
 
+    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+        <option name="force-skip-system-props" value="true" />
+        <option name="set-global-setting" key="verifier_engprod" value="1" />
+        <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+        <option name="restore-settings" value="true" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="install-arg" value="-t" />
diff --git a/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java
index 472a82c..d5638e9 100644
--- a/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java
@@ -57,8 +57,9 @@
 
     private ResolveInfo mResolveInfo1 = new ResolveInfo();
     private ResolveInfo mResolveInfo2 = new ResolveInfo();
-    private final String mTestPkg1 = "testPkg1", mTestPkg2 = "testPkg2", mTestPkg3 = "testPkg3";
-    private final String mMusicFxPkgName = "com.android.musicfx";
+    private final String mTestPkg1 = new String("testPkg1"), mTestPkg2 = new String("testPkg2"),
+            mTestPkg3 = new String("testPkg3"), mTestPkg1Equivalent = new String("testPkg1");
+    private final String mMusicFxPkgName = new String("com.android.musicfx");
     private final int mTestUid1 = 1, mTestUid2 = 2, mTestUid3 = 3, mMusicFxUid = 78;
     private final int mTestSession1 = 11, mTestSession2 = 22, mTestSession3 = 33;
 
@@ -191,7 +192,8 @@
     public void testCloseBroadcastIntent() {
         Log.i(TAG, "running testCloseBroadcastIntent");
 
-        closeSessionWithResList(null, 0, 0, null, mTestSession1, mTestUid1);
+        closeSessionWithResList(null, 0 /* unbind */, 0 /* broadcast */, null /* packageName */,
+                mTestSession1, mTestUid1);
     }
 
     /**
@@ -225,8 +227,10 @@
     public void testBroadcastIntentWithNoPackageAndNoBroadcastReceiver() {
         Log.i(TAG, "running testBroadcastIntentWithNoPackageAndNoBroadcastReceiver");
 
-        openSessionWithResList(mEmptyList, 0, 0, null, mTestSession1, mTestUid1);
-        closeSessionWithResList(mEmptyList, 0, 0, null, mTestSession1, mTestUid1);
+        openSessionWithResList(mEmptyList, 0 /* bind */, 0 /* broadcast */, null /* packageName */,
+                mTestSession1, mTestUid1);
+        closeSessionWithResList(mEmptyList, 0 /* unbind */, 0 /* broadcast */,
+                null /* packageName */, mTestSession1, mTestUid1);
     }
 
     /**
@@ -236,26 +240,10 @@
     public void testBroadcastIntentWithNoPackageAndOneBroadcastReceiver() {
         Log.i(TAG, "running testBroadcastIntentWithNoPackageAndOneBroadcastReceiver");
 
-        int broadcasts = 1, bind = 1, unbind = 1;
-        openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession1, mTestUid1);
-        broadcasts = broadcasts + 1;
-        closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession1, mTestUid1);
-
-        // repeat with different session ID
-        broadcasts = broadcasts + 1;
-        bind = bind + 1;
-        unbind = unbind + 1;
-        openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession2, mTestUid1);
-        broadcasts = broadcasts + 1;
-        closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession2, mTestUid1);
-
-        // repeat with different UID
-        broadcasts = broadcasts + 1;
-        bind = bind + 1;
-        unbind = unbind + 1;
-        openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession1, mTestUid2);
-        broadcasts = broadcasts + 1;
-        closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession1, mTestUid2);
+        openSessionWithResList(mSingleList, 0 /* bind */, 0 /* broadcast */,
+                null /* packageName */, mTestSession1, mTestUid1);
+        closeSessionWithResList(mSingleList, 0 /* unbind */, 0 /* broadcast */,
+                null /* packageName */, mTestSession1, mTestUid1);
     }
 
     /**
@@ -265,8 +253,50 @@
     public void testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers() {
         Log.i(TAG, "running testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers");
 
-        openSessionWithResList(mDoubleList, 1, 1, null, mTestSession1, mTestUid1);
-        closeSessionWithResList(mDoubleList, 1, 2, null, mTestSession1, mTestUid1);
+        openSessionWithResList(mDoubleList, 0 /* bind */, 0 /* broadcast */,
+                null /* packageName */, mTestSession1, mTestUid1);
+        closeSessionWithResList(mDoubleList, 0 /* bind */, 0 /* broadcast */,
+                null /* packageName */, mTestSession1, mTestUid1);
+    }
+
+    @Test
+    public void testBroadcastIntentWithPackageAndOneBroadcastReceiver() {
+        Log.i(TAG, "running testBroadcastIntentWithPackageAndOneBroadcastReceiver");
+
+        int broadcasts = 1, bind = 1, unbind = 1;
+        openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg1, mTestSession1, mTestUid1);
+
+        broadcasts = broadcasts + 1;
+        closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg1, mTestSession1,
+                mTestUid1);
+
+        // repeat with different session ID
+        broadcasts = broadcasts + 1;
+        bind = bind + 1;
+        unbind = unbind + 1;
+        openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg2, mTestSession2, mTestUid1);
+        broadcasts = broadcasts + 1;
+        closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg2, mTestSession2,
+                mTestUid1);
+
+        // repeat with different UID
+        broadcasts = broadcasts + 1;
+        bind = bind + 1;
+        unbind = unbind + 1;
+        openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg3, mTestSession1, mTestUid2);
+        broadcasts = broadcasts + 1;
+        closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg3, mTestSession1,
+                mTestUid2);
+    }
+
+    @Test
+    public void testBroadcastIntentWithPackageAndTwoBroadcastReceivers() {
+        Log.i(TAG, "running testBroadcastIntentWithPackageAndTwoBroadcastReceivers");
+
+        openSessionWithResList(mDoubleList, 1 /* bind */, 1 /* broadcast */,
+                mTestPkg1 /* packageName */, mTestSession1, mTestUid1);
+        closeSessionWithResList(mDoubleList, 1 /* unbind */, 2 /* broadcast */,
+                mTestPkg1 /* packageName */, mTestSession1, mTestUid1);
     }
 
     /**
@@ -639,4 +669,18 @@
         unbind = unbind + 1;
         sendMessage(MusicFxHelper.MSG_EFFECT_CLIENT_GONE, mTestUid3, unbind, broadcasts);
     }
+
+    /**
+     * Test audio session open/close with same package name value but different String object.
+     */
+    @Test
+    public void testSessionOpenCloseWithSamePackageNameValueButDiffObject() {
+        Log.i(TAG, "running testSessionOpenCloseWithSamePackageNameValueButDiffObject");
+        int broadcasts = 1;
+        openSessionWithResList(mSingleList, 1 /* bind */, broadcasts, mTestPkg1, mTestSession1,
+                mTestUid1);
+        closeSessionWithResList(mSingleList, 1 /* unbind */, broadcasts + 1, mTestPkg1Equivalent,
+                mTestSession1, mTestUid1);
+    }
+
 }
diff --git a/services/tests/servicestests/src/com/android/server/autofill/OWNERS b/services/tests/servicestests/src/com/android/server/autofill/OWNERS
new file mode 100644
index 0000000..70106d1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/autofill/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/autofill/OWNERS
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
index d6d2b6d..2a49a86 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
@@ -19,9 +19,16 @@
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN;
+import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
+import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
+import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
+import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
 import static android.util.DebugUtils.valueToString;
 
 import static org.junit.Assert.assertEquals;
@@ -51,7 +58,10 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.test.FakePermissionEnforcer;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArrayMap;
 
@@ -62,6 +72,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -84,6 +95,9 @@
     @Mock private IBatteryStats.Stub mBatteryStatsService;
     @Mock private INetd.Stub mNetdService;
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
     private static final int TEST_UID = 111;
 
     @NonNull
@@ -254,6 +268,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS)
     public void testMeteredNetworkRestrictions() throws RemoteException {
         // Make sure the mocked netd method returns true.
         doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean());
@@ -295,6 +310,69 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS)
+    public void testMeteredNetworkRestrictionsByAdminChain() {
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID,
+                FIREWALL_RULE_DENY);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID,
+                FIREWALL_RULE_DENY);
+        assertTrue("Should be true since mobile data usage is restricted by admin chain",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        assertFalse("Should be false since mobile data usage is no longer restricted by admin",
+                mNMService.isNetworkRestricted(TEST_UID));
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS)
+    public void testMeteredNetworkRestrictionsByUserChain() {
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID,
+                FIREWALL_RULE_DENY);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID,
+                FIREWALL_RULE_DENY);
+        assertTrue("Should be true since mobile data usage is restricted by user chain",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        assertFalse("Should be false since mobile data usage is no longer restricted by user",
+                mNMService.isNetworkRestricted(TEST_UID));
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS)
+    public void testDataSaverRestrictionsWithAllowChain() {
+        mNMService.setDataSaverModeEnabled(true);
+        verify(mCm).setDataSaverEnabled(true);
+
+        assertTrue("Should be true since data saver is on and the uid is not allowlisted",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, FIREWALL_RULE_ALLOW);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, FIREWALL_RULE_ALLOW);
+        assertFalse("Should be false since data saver is on and the uid is allowlisted",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        // remove uid from allowlist and turn datasaver off again
+
+        mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID,
+                FIREWALL_RULE_DEFAULT);
+        mNMService.setDataSaverModeEnabled(false);
+        verify(mCm).setDataSaverEnabled(false);
+
+        assertFalse("Network should not be restricted when data saver is off",
+                mNMService.isNetworkRestricted(TEST_UID));
+    }
+
+    @Test
     public void testFirewallChains() {
         final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>();
         // Dozable chain
diff --git a/tests/BinderLeakTest/Android.bp b/tests/BinderLeakTest/Android.bp
index 78b0ede..3747d04 100644
--- a/tests/BinderLeakTest/Android.bp
+++ b/tests/BinderLeakTest/Android.bp
@@ -24,6 +24,9 @@
         "androidx.test.rules",
         "androidx.test.runner",
     ],
+    test_suites: [
+        "general-tests",
+    ],
 }
 
 // Built with target_sdk_version: current
diff --git a/tests/FlickerTests/IME/Android.bp b/tests/FlickerTests/IME/Android.bp
index 1141e5f..358c490 100644
--- a/tests/FlickerTests/IME/Android.bp
+++ b/tests/FlickerTests/IME/Android.bp
@@ -55,6 +55,10 @@
     defaults: ["FlickerTestsDefault"],
     manifest: "AndroidManifest.xml",
     test_config_template: "AndroidTestTemplate.xml",
+    test_suites: [
+        "device-tests",
+        "device-platinum-tests",
+    ],
     srcs: [":FlickerTestsIme1-src"],
     static_libs: [
         "FlickerTestsBase",
diff --git a/tests/FlickerTests/IME/OWNERS b/tests/FlickerTests/IME/OWNERS
index 301fafa..ae1098d 100644
--- a/tests/FlickerTests/IME/OWNERS
+++ b/tests/FlickerTests/IME/OWNERS
@@ -1,2 +1,3 @@
 # ime
 # Bug component: 34867
+include /services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/tests/FlickerTests/Rotation/Android.bp b/tests/FlickerTests/Rotation/Android.bp
index 233a276..6a0d9ef 100644
--- a/tests/FlickerTests/Rotation/Android.bp
+++ b/tests/FlickerTests/Rotation/Android.bp
@@ -28,6 +28,10 @@
     defaults: ["FlickerTestsDefault"],
     manifest: "AndroidManifest.xml",
     test_config_template: "AndroidTestTemplate.xml",
+    test_suites: [
+        "device-tests",
+        "device-platinum-tests",
+    ],
     srcs: ["src/**/*"],
     static_libs: ["FlickerTestsBase"],
     data: ["trace_config/*"],
diff --git a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
index 3a2a3be..ae32bda 100644
--- a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
+++ b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
@@ -16,6 +16,8 @@
 
 package android.hardware.input
 
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.content.ContextWrapper
 import android.graphics.drawable.Drawable
 import android.platform.test.annotations.Presubmit
@@ -54,16 +56,16 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
     fun testKeyboardLayoutDrawable_hasCorrectDimensions() {
-        setFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
         val drawable = createDrawable()!!
         assertEquals(WIDTH, drawable.intrinsicWidth)
         assertEquals(HEIGHT, drawable.intrinsicHeight)
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
     fun testKeyboardLayoutDrawable_isNull_ifFlagOff() {
-        setFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
         assertNull(createDrawable())
     }
 }
\ No newline at end of file
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 093923f..a8b383c 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -101,8 +101,8 @@
     private static final String OBSERVER_NAME_2 = "observer2";
     private static final String OBSERVER_NAME_3 = "observer3";
     private static final String OBSERVER_NAME_4 = "observer4";
-    private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(1);
-    private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(5);
+    private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(10);
+    private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(50);
 
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -1453,7 +1453,8 @@
         raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
                 VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
 
-        moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS);
+        moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS
+                - TimeUnit.MINUTES.toMillis(1));
 
         // The first failure will be outside the threshold.
         raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
@@ -1712,6 +1713,9 @@
             watchdog.onPackageFailure(packages, failureReason);
         }
         mTestLooper.dispatchAll();
+        if (Flags.recoverabilityDetection()) {
+            moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
+        }
     }
 
     private PackageWatchdog createWatchdog() {
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 960b57c..580efe1 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -70,6 +70,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Uri;
+import android.net.vcn.Flags;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
@@ -82,7 +83,9 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.test.TestLooper;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -101,6 +104,7 @@
 import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -118,6 +122,8 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnManagementServiceTest {
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final String CONTEXT_ATTRIBUTION_TAG = "VCN";
     private static final String TEST_PACKAGE_NAME =
             VcnManagementServiceTest.class.getPackage().getName();
@@ -129,7 +135,12 @@
     private static final ParcelUuid TEST_UUID_3 = new ParcelUuid(new UUID(2, 2));
     private static final VcnConfig TEST_VCN_CONFIG;
     private static final VcnConfig TEST_VCN_CONFIG_PKG_2;
-    private static final int TEST_UID = Process.FIRST_APPLICATION_UID;
+
+    private static final int TEST_UID = 1010000; // A non-system user
+    private static final UserHandle TEST_USER_HANDLE = UserHandle.getUserHandleForUid(TEST_UID);
+    private static final UserHandle TEST_USER_HANDLE_OTHER =
+            UserHandle.of(TEST_USER_HANDLE.getIdentifier() + 1);
+
     private static final String TEST_IFACE_NAME = "TEST_IFACE";
     private static final String TEST_IFACE_NAME_2 = "TEST_IFACE2";
     private static final LinkProperties TEST_LP_1 = new LinkProperties();
@@ -187,6 +198,7 @@
     private final TelephonyManager mTelMgr = mock(TelephonyManager.class);
     private final SubscriptionManager mSubMgr = mock(SubscriptionManager.class);
     private final AppOpsManager mAppOpsMgr = mock(AppOpsManager.class);
+    private final UserManager mUserManager = mock(UserManager.class);
     private final VcnContext mVcnContext = mock(VcnContext.class);
     private final PersistableBundleUtils.LockingReadWriteHelper mConfigReadWriteHelper =
             mock(PersistableBundleUtils.LockingReadWriteHelper.class);
@@ -218,6 +230,9 @@
                 Context.TELEPHONY_SUBSCRIPTION_SERVICE,
                 SubscriptionManager.class);
         setupSystemService(mMockContext, mAppOpsMgr, Context.APP_OPS_SERVICE, AppOpsManager.class);
+        setupSystemService(mMockContext, mUserManager, Context.USER_SERVICE, UserManager.class);
+
+        doReturn(TEST_USER_HANDLE).when(mUserManager).getMainUser();
 
         doReturn(TEST_PACKAGE_NAME).when(mMockContext).getOpPackageName();
 
@@ -267,6 +282,8 @@
 
     @Before
     public void setUp() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENFORCE_MAIN_USER);
+
         doNothing()
                 .when(mMockContext)
                 .enforceCallingOrSelfPermission(
@@ -717,10 +734,8 @@
     }
 
     @Test
-    public void testSetVcnConfigRequiresSystemUser() throws Exception {
-        doReturn(UserHandle.getUid(UserHandle.MIN_SECONDARY_USER_ID, TEST_UID))
-                .when(mMockDeps)
-                .getBinderCallingUid();
+    public void testSetVcnConfigRequiresMainUser() throws Exception {
+        doReturn(TEST_USER_HANDLE_OTHER).when(mUserManager).getMainUser();
 
         try {
             mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
@@ -832,10 +847,8 @@
     }
 
     @Test
-    public void testClearVcnConfigRequiresSystemUser() throws Exception {
-        doReturn(UserHandle.getUid(UserHandle.MIN_SECONDARY_USER_ID, TEST_UID))
-                .when(mMockDeps)
-                .getBinderCallingUid();
+    public void testClearVcnConfigRequiresMainUser() throws Exception {
+        doReturn(TEST_USER_HANDLE_OTHER).when(mUserManager).getMainUser();
 
         try {
             mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
@@ -921,10 +934,8 @@
     }
 
     @Test
-    public void testGetConfiguredSubscriptionGroupsRequiresSystemUser() throws Exception {
-        doReturn(UserHandle.getUid(UserHandle.MIN_SECONDARY_USER_ID, TEST_UID))
-                .when(mMockDeps)
-                .getBinderCallingUid();
+    public void testGetConfiguredSubscriptionGroupsRequiresMainUser() throws Exception {
+        doReturn(TEST_USER_HANDLE_OTHER).when(mUserManager).getMainUser();
 
         try {
             mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
index c8b60e5..441a4ae 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
@@ -20,6 +20,7 @@
 import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY;
 import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_POLL_IPSEC_STATE_INTERVAL_SECONDS_KEY;
 
+import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR;
 import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.MIN_VALID_EXPECTED_RX_PACKET_NUM;
 import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.getMaxSeqNumIncreasePerSecond;
 import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
@@ -584,4 +585,56 @@
                 MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED,
                 getMaxSeqNumIncreasePerSecond(mCarrierConfig));
     }
+
+    private IpSecPacketLossDetector newDetectorAndSetTransform(int threshold) throws Exception {
+        when(mCarrierConfig.getInt(
+                        eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY),
+                        anyInt()))
+                .thenReturn(threshold);
+
+        final IpSecPacketLossDetector detector =
+                new IpSecPacketLossDetector(
+                        mVcnContext,
+                        mNetwork,
+                        mCarrierConfig,
+                        mMetricMonitorCallback,
+                        mDependencies);
+
+        detector.setIsSelectedUnderlyingNetwork(true /* setIsSelected */);
+        detector.setInboundTransformInternal(mIpSecTransform);
+
+        return detector;
+    }
+
+    @Test
+    public void testDisableAndEnableDetectorWithCarrierConfig() throws Exception {
+        final IpSecPacketLossDetector detector =
+                newDetectorAndSetTransform(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR);
+
+        assertFalse(detector.isStarted());
+
+        when(mCarrierConfig.getInt(
+                        eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY),
+                        anyInt()))
+                .thenReturn(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD);
+        detector.setCarrierConfig(mCarrierConfig);
+
+        assertTrue(detector.isStarted());
+    }
+
+    @Test
+    public void testEnableAndDisableDetectorWithCarrierConfig() throws Exception {
+        final IpSecPacketLossDetector detector =
+                newDetectorAndSetTransform(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD);
+
+        assertTrue(detector.isStarted());
+
+        when(mCarrierConfig.getInt(
+                        eq(VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY),
+                        anyInt()))
+                .thenReturn(IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_DISABLE_DETECTOR);
+        detector.setCarrierConfig(mCarrierConfig);
+
+        assertFalse(detector.isStarted());
+    }
 }
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
index edad678..0439d5f5 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
@@ -123,6 +123,7 @@
         mSetFlagsRule.enableFlags(Flags.FLAG_VALIDATE_NETWORK_ON_IPSEC_LOSS);
         mSetFlagsRule.enableFlags(Flags.FLAG_EVALUATE_IPSEC_LOSS_ON_LP_NC_CHANGE);
         mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_SEQ_NUM_LEAP);
+        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_DISABLE_IPSEC_LOSS_DETECTOR);
 
         when(mNetwork.getNetId()).thenReturn(-1);
 
diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h
index de1d60c..24c3208 100644
--- a/tools/aapt/Symbol.h
+++ b/tools/aapt/Symbol.h
@@ -40,7 +40,7 @@
 };
 
 /**
- * A specific defintion of a symbol, defined with a configuration and a definition site.
+ * A specific definition of a symbol, defined with a configuration and a definition site.
  */
 struct SymbolDefinition {
     inline SymbolDefinition();
@@ -92,4 +92,3 @@
 }
 
 #endif // AAPT_SYMBOL_H
-
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index b56b4c4..57459e3 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -441,7 +441,7 @@
   manifest_action.Action(AutoGenerateIsSplitRequired);
   manifest_action.Action(VerifyManifest);
   manifest_action.Action(FixCoreAppAttribute);
-  manifest_action.Action([&](xml::Element* el) -> bool {
+  manifest_action.Action([this, diag](xml::Element* el) -> bool {
     EnsureNamespaceIsDeclared("android", xml::kSchemaAndroid, &el->namespace_decls);
 
     if (options_.version_name_default) {
@@ -504,7 +504,7 @@
   manifest_action["eat-comment"];
 
   // Uses-sdk actions.
-  manifest_action["uses-sdk"].Action([&](xml::Element* el) -> bool {
+  manifest_action["uses-sdk"].Action([this](xml::Element* el) -> bool {
     if (options_.min_sdk_version_default &&
         el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion") == nullptr) {
       // There was no minSdkVersion defined and we have a default to assign.
@@ -526,7 +526,7 @@
 
   // Instrumentation actions.
   manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
-  manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
+  manifest_action["instrumentation"].Action([this](xml::Element* el) -> bool {
     if (!options_.rename_instrumentation_target_package) {
       return true;
     }
@@ -542,7 +542,7 @@
   manifest_action["attribution"];
   manifest_action["attribution"]["inherit-from"];
   manifest_action["original-package"];
-  manifest_action["overlay"].Action([&](xml::Element* el) -> bool {
+  manifest_action["overlay"].Action([this](xml::Element* el) -> bool {
     if (options_.rename_overlay_target_package) {
       if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "targetPackage")) {
         attr->value = options_.rename_overlay_target_package.value();
@@ -623,7 +623,7 @@
   uses_package_action["additional-certificate"];
 
   if (options_.debug_mode) {
-    application_action.Action([&](xml::Element* el) -> bool {
+    application_action.Action([](xml::Element* el) -> bool {
       xml::Attribute *attr = el->FindOrCreateAttribute(xml::kSchemaAndroid, "debuggable");
       attr->value = "true";
       return true;
diff --git a/tools/hoststubgen/OWNERS b/tools/hoststubgen/OWNERS
index a8c5321..3d8888d 100644
--- a/tools/hoststubgen/OWNERS
+++ b/tools/hoststubgen/OWNERS
@@ -1,3 +1 @@
-omakoto@google.com
-jsharkey@google.com
-jaggies@google.com
+file:platform/frameworks/base:/ravenwood/OWNERS